1 //
2 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // Surface.cpp: Implements the egl::Surface class, representing a drawing surface
8 // such as the client area of a window, including any back buffers.
9 // Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.
10
11 #include "libANGLE/Surface.h"
12
13 #include <EGL/eglext.h>
14
15 #include "libANGLE/Config.h"
16 #include "libANGLE/Context.h"
17 #include "libANGLE/Display.h"
18 #include "libANGLE/Framebuffer.h"
19 #include "libANGLE/Texture.h"
20 #include "libANGLE/formatutils.h"
21 #include "libANGLE/renderer/EGLImplFactory.h"
22 #include "libANGLE/trace.h"
23
24 namespace egl
25 {
26 namespace
27 {
28 angle::SubjectIndex kSurfaceImplSubjectIndex = 0;
29 } // namespace
30
SurfaceState(const egl::Config * configIn,const AttributeMap & attributesIn)31 SurfaceState::SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn)
32 : label(nullptr),
33 config((configIn != nullptr) ? new egl::Config(*configIn) : nullptr),
34 attributes(attributesIn),
35 timestampsEnabled(false),
36 directComposition(false)
37 {
38 directComposition = attributes.get(EGL_DIRECT_COMPOSITION_ANGLE, EGL_FALSE) == EGL_TRUE;
39 }
40
~SurfaceState()41 SurfaceState::~SurfaceState()
42 {
43 delete config;
44 }
45
isRobustResourceInitEnabled() const46 bool SurfaceState::isRobustResourceInitEnabled() const
47 {
48 return attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE;
49 }
50
Surface(EGLint surfaceType,const egl::Config * config,const AttributeMap & attributes,EGLenum buftype)51 Surface::Surface(EGLint surfaceType,
52 const egl::Config *config,
53 const AttributeMap &attributes,
54 EGLenum buftype)
55 : FramebufferAttachmentObject(),
56 mState(config, attributes),
57 mImplementation(nullptr),
58 mRefCount(0),
59 mDestroyed(false),
60 mType(surfaceType),
61 mBuftype(buftype),
62 mPostSubBufferRequested(false),
63 mLargestPbuffer(false),
64 mGLColorspace(EGL_GL_COLORSPACE_LINEAR),
65 mVGAlphaFormat(EGL_VG_ALPHA_FORMAT_NONPRE),
66 mVGColorspace(EGL_VG_COLORSPACE_sRGB),
67 mMipmapTexture(false),
68 mMipmapLevel(0),
69 mHorizontalResolution(EGL_UNKNOWN),
70 mVerticalResolution(EGL_UNKNOWN),
71 mMultisampleResolve(EGL_MULTISAMPLE_RESOLVE_DEFAULT),
72 mFixedSize(false),
73 mFixedWidth(0),
74 mFixedHeight(0),
75 mTextureFormat(TextureFormat::NoTexture),
76 mTextureTarget(EGL_NO_TEXTURE),
77 // FIXME: Determine actual pixel aspect ratio
78 mPixelAspectRatio(static_cast<EGLint>(1.0 * EGL_DISPLAY_SCALING)),
79 mRenderBuffer(EGL_BACK_BUFFER),
80 mSwapBehavior(EGL_NONE),
81 mOrientation(0),
82 mTexture(nullptr),
83 mColorFormat(config->renderTargetFormat),
84 mDSFormat(config->depthStencilFormat),
85 mInitState(gl::InitState::Initialized),
86 mImplObserverBinding(this, kSurfaceImplSubjectIndex)
87 {
88 mPostSubBufferRequested =
89 (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE);
90 mFlexibleSurfaceCompatibilityRequested =
91 (attributes.get(EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, EGL_FALSE) == EGL_TRUE);
92
93 if (mType == EGL_PBUFFER_BIT)
94 {
95 mLargestPbuffer = (attributes.get(EGL_LARGEST_PBUFFER, EGL_FALSE) == EGL_TRUE);
96 }
97
98 if (mType == EGL_PIXMAP_BIT)
99 {
100 mRenderBuffer = EGL_SINGLE_BUFFER;
101 }
102
103 mGLColorspace =
104 static_cast<EGLenum>(attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR));
105 mVGAlphaFormat =
106 static_cast<EGLenum>(attributes.get(EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_NONPRE));
107 mVGColorspace = static_cast<EGLenum>(attributes.get(EGL_VG_COLORSPACE, EGL_VG_COLORSPACE_sRGB));
108 mMipmapTexture = (attributes.get(EGL_MIPMAP_TEXTURE, EGL_FALSE) == EGL_TRUE);
109
110 mRobustResourceInitialization =
111 (attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
112 if (mRobustResourceInitialization)
113 {
114 mInitState = gl::InitState::MayNeedInit;
115 }
116
117 mFixedSize = (attributes.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE);
118 if (mFixedSize)
119 {
120 mFixedWidth = static_cast<size_t>(attributes.get(EGL_WIDTH, 0));
121 mFixedHeight = static_cast<size_t>(attributes.get(EGL_HEIGHT, 0));
122 }
123
124 if (mType != EGL_WINDOW_BIT)
125 {
126 mTextureFormat = attributes.getAsPackedEnum(EGL_TEXTURE_FORMAT, TextureFormat::NoTexture);
127 mTextureTarget = static_cast<EGLenum>(attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE));
128 }
129
130 mOrientation = static_cast<EGLint>(attributes.get(EGL_SURFACE_ORIENTATION_ANGLE, 0));
131
132 mTextureOffset.x = static_cast<int>(mState.attributes.get(EGL_TEXTURE_OFFSET_X_ANGLE, 0));
133 mTextureOffset.y = static_cast<int>(mState.attributes.get(EGL_TEXTURE_OFFSET_Y_ANGLE, 0));
134 }
135
~Surface()136 Surface::~Surface() {}
137
getAttachmentImpl() const138 rx::FramebufferAttachmentObjectImpl *Surface::getAttachmentImpl() const
139 {
140 return mImplementation;
141 }
142
destroyImpl(const Display * display)143 Error Surface::destroyImpl(const Display *display)
144 {
145 if (mImplementation)
146 {
147 mImplementation->destroy(display);
148 }
149
150 ASSERT(!mTexture);
151
152 SafeDelete(mImplementation);
153
154 delete this;
155 return NoError();
156 }
157
postSwap(const gl::Context * context)158 void Surface::postSwap(const gl::Context *context)
159 {
160 if (mRobustResourceInitialization && mSwapBehavior != EGL_BUFFER_PRESERVED)
161 {
162 mInitState = gl::InitState::MayNeedInit;
163 onStateChange(angle::SubjectMessage::SubjectChanged);
164 }
165 }
166
initialize(const Display * display)167 Error Surface::initialize(const Display *display)
168 {
169 GLenum overrideRenderTargetFormat = mState.config->renderTargetFormat;
170
171 // To account for color space differences, override the renderTargetFormat with the
172 // non-linear format. If no suitable non-linear format was found, return
173 // EGL_BAD_MATCH error
174 if (!gl::ColorspaceFormatOverride(mGLColorspace, &overrideRenderTargetFormat))
175 {
176 return egl::EglBadMatch();
177 }
178
179 // If an override is required update mState.config as well
180 if (mState.config->renderTargetFormat != overrideRenderTargetFormat)
181 {
182 egl::Config *overrideConfig = new egl::Config(*(mState.config));
183 overrideConfig->renderTargetFormat = overrideRenderTargetFormat;
184 delete mState.config;
185 mState.config = overrideConfig;
186
187 mColorFormat = gl::Format(mState.config->renderTargetFormat);
188 mDSFormat = gl::Format(mState.config->depthStencilFormat);
189 }
190
191 ANGLE_TRY(mImplementation->initialize(display));
192
193 // Initialized here since impl is nullptr in the constructor.
194 // Must happen after implementation initialize for Android.
195 mSwapBehavior = mImplementation->getSwapBehavior();
196
197 if (mBuftype == EGL_IOSURFACE_ANGLE)
198 {
199 GLenum internalFormat =
200 static_cast<GLenum>(mState.attributes.get(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE));
201 GLenum type = static_cast<GLenum>(mState.attributes.get(EGL_TEXTURE_TYPE_ANGLE));
202
203 // GL_RGBA + GL_HALF_FLOAT is not a valid format/type combination in GLES like it is in
204 // desktop GL. Adjust the frontend format to be sized RGBA16F.
205 if (internalFormat == GL_RGBA && type == GL_HALF_FLOAT)
206 {
207 internalFormat = GL_RGBA16F;
208 }
209 mColorFormat = gl::Format(internalFormat, type);
210 }
211 if (mBuftype == EGL_D3D_TEXTURE_ANGLE)
212 {
213 const angle::Format *colorFormat = mImplementation->getD3DTextureColorFormat();
214 ASSERT(colorFormat != nullptr);
215 GLenum internalFormat = colorFormat->fboImplementationInternalFormat;
216 mColorFormat = gl::Format(internalFormat, colorFormat->componentType);
217 mGLColorspace = EGL_GL_COLORSPACE_LINEAR;
218 if (mColorFormat.info->colorEncoding == GL_SRGB)
219 {
220 mGLColorspace = EGL_GL_COLORSPACE_SRGB;
221 }
222 }
223
224 if (mType == EGL_WINDOW_BIT && display->getExtensions().getFrameTimestamps)
225 {
226 mState.supportedCompositorTimings = mImplementation->getSupportedCompositorTimings();
227 mState.supportedTimestamps = mImplementation->getSupportedTimestamps();
228 }
229
230 mImplObserverBinding.bind(mImplementation);
231
232 return NoError();
233 }
234
makeCurrent(const gl::Context * context)235 Error Surface::makeCurrent(const gl::Context *context)
236 {
237 ANGLE_TRY(mImplementation->makeCurrent(context));
238
239 mRefCount++;
240 return NoError();
241 }
242
unMakeCurrent(const gl::Context * context)243 Error Surface::unMakeCurrent(const gl::Context *context)
244 {
245 ANGLE_TRY(mImplementation->unMakeCurrent(context));
246 return releaseRef(context->getDisplay());
247 }
248
releaseRef(const Display * display)249 Error Surface::releaseRef(const Display *display)
250 {
251 ASSERT(mRefCount > 0);
252 mRefCount--;
253 if (mRefCount == 0 && mDestroyed)
254 {
255 ASSERT(display);
256 return destroyImpl(display);
257 }
258
259 return NoError();
260 }
261
onDestroy(const Display * display)262 Error Surface::onDestroy(const Display *display)
263 {
264 mDestroyed = true;
265 if (mRefCount == 0)
266 {
267 return destroyImpl(display);
268 }
269 return NoError();
270 }
271
setLabel(EGLLabelKHR label)272 void Surface::setLabel(EGLLabelKHR label)
273 {
274 mState.label = label;
275 }
276
getLabel() const277 EGLLabelKHR Surface::getLabel() const
278 {
279 return mState.label;
280 }
281
getType() const282 EGLint Surface::getType() const
283 {
284 return mType;
285 }
286
swap(const gl::Context * context)287 Error Surface::swap(const gl::Context *context)
288 {
289 ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swap");
290 context->onPreSwap();
291
292 context->getState().getOverlay()->onSwap();
293
294 ANGLE_TRY(mImplementation->swap(context));
295 postSwap(context);
296 return NoError();
297 }
298
swapWithDamage(const gl::Context * context,const EGLint * rects,EGLint n_rects)299 Error Surface::swapWithDamage(const gl::Context *context, const EGLint *rects, EGLint n_rects)
300 {
301 ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swapWithDamage");
302 context->onPreSwap();
303
304 context->getState().getOverlay()->onSwap();
305
306 ANGLE_TRY(mImplementation->swapWithDamage(context, rects, n_rects));
307 postSwap(context);
308 return NoError();
309 }
310
swapWithFrameToken(const gl::Context * context,EGLFrameTokenANGLE frameToken)311 Error Surface::swapWithFrameToken(const gl::Context *context, EGLFrameTokenANGLE frameToken)
312 {
313 ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swapWithFrameToken");
314 context->onPreSwap();
315
316 context->getState().getOverlay()->onSwap();
317
318 ANGLE_TRY(mImplementation->swapWithFrameToken(context, frameToken));
319 postSwap(context);
320 return NoError();
321 }
322
postSubBuffer(const gl::Context * context,EGLint x,EGLint y,EGLint width,EGLint height)323 Error Surface::postSubBuffer(const gl::Context *context,
324 EGLint x,
325 EGLint y,
326 EGLint width,
327 EGLint height)
328 {
329 if (width == 0 || height == 0)
330 {
331 return egl::NoError();
332 }
333
334 context->getState().getOverlay()->onSwap();
335
336 ANGLE_TRY(mImplementation->postSubBuffer(context, x, y, width, height));
337 postSwap(context);
338 return NoError();
339 }
340
setPresentationTime(EGLnsecsANDROID time)341 Error Surface::setPresentationTime(EGLnsecsANDROID time)
342 {
343 return mImplementation->setPresentationTime(time);
344 }
345
querySurfacePointerANGLE(EGLint attribute,void ** value)346 Error Surface::querySurfacePointerANGLE(EGLint attribute, void **value)
347 {
348 return mImplementation->querySurfacePointerANGLE(attribute, value);
349 }
350
isPostSubBufferSupported() const351 EGLint Surface::isPostSubBufferSupported() const
352 {
353 return mPostSubBufferRequested && mImplementation->isPostSubBufferSupported();
354 }
355
setSwapInterval(EGLint interval)356 void Surface::setSwapInterval(EGLint interval)
357 {
358 mImplementation->setSwapInterval(interval);
359 }
360
setMipmapLevel(EGLint level)361 void Surface::setMipmapLevel(EGLint level)
362 {
363 // Level is set but ignored
364 UNIMPLEMENTED();
365 mMipmapLevel = level;
366 }
367
setMultisampleResolve(EGLenum resolve)368 void Surface::setMultisampleResolve(EGLenum resolve)
369 {
370 // Behaviour is set but ignored
371 UNIMPLEMENTED();
372 mMultisampleResolve = resolve;
373 }
374
setSwapBehavior(EGLenum behavior)375 void Surface::setSwapBehavior(EGLenum behavior)
376 {
377 // Behaviour is set but ignored
378 UNIMPLEMENTED();
379 mSwapBehavior = behavior;
380 }
381
setFixedWidth(EGLint width)382 void Surface::setFixedWidth(EGLint width)
383 {
384 mFixedWidth = width;
385 mImplementation->setFixedWidth(width);
386 }
387
setFixedHeight(EGLint height)388 void Surface::setFixedHeight(EGLint height)
389 {
390 mFixedHeight = height;
391 mImplementation->setFixedHeight(height);
392 }
393
getConfig() const394 const Config *Surface::getConfig() const
395 {
396 return mState.config;
397 }
398
getPixelAspectRatio() const399 EGLint Surface::getPixelAspectRatio() const
400 {
401 return mPixelAspectRatio;
402 }
403
getRenderBuffer() const404 EGLenum Surface::getRenderBuffer() const
405 {
406 return mRenderBuffer;
407 }
408
getSwapBehavior() const409 EGLenum Surface::getSwapBehavior() const
410 {
411 return mSwapBehavior;
412 }
413
getTextureFormat() const414 TextureFormat Surface::getTextureFormat() const
415 {
416 return mTextureFormat;
417 }
418
getTextureTarget() const419 EGLenum Surface::getTextureTarget() const
420 {
421 return mTextureTarget;
422 }
423
getLargestPbuffer() const424 bool Surface::getLargestPbuffer() const
425 {
426 return mLargestPbuffer;
427 }
428
getGLColorspace() const429 EGLenum Surface::getGLColorspace() const
430 {
431 return mGLColorspace;
432 }
433
getVGAlphaFormat() const434 EGLenum Surface::getVGAlphaFormat() const
435 {
436 return mVGAlphaFormat;
437 }
438
getVGColorspace() const439 EGLenum Surface::getVGColorspace() const
440 {
441 return mVGColorspace;
442 }
443
getMipmapTexture() const444 bool Surface::getMipmapTexture() const
445 {
446 return mMipmapTexture;
447 }
448
getMipmapLevel() const449 EGLint Surface::getMipmapLevel() const
450 {
451 return mMipmapLevel;
452 }
453
getHorizontalResolution() const454 EGLint Surface::getHorizontalResolution() const
455 {
456 return mHorizontalResolution;
457 }
458
getVerticalResolution() const459 EGLint Surface::getVerticalResolution() const
460 {
461 return mVerticalResolution;
462 }
463
getMultisampleResolve() const464 EGLenum Surface::getMultisampleResolve() const
465 {
466 return mMultisampleResolve;
467 }
468
isFixedSize() const469 EGLint Surface::isFixedSize() const
470 {
471 return mFixedSize;
472 }
473
getWidth() const474 EGLint Surface::getWidth() const
475 {
476 return mFixedSize ? static_cast<EGLint>(mFixedWidth) : mImplementation->getWidth();
477 }
478
getHeight() const479 EGLint Surface::getHeight() const
480 {
481 return mFixedSize ? static_cast<EGLint>(mFixedHeight) : mImplementation->getHeight();
482 }
483
getUserWidth(const egl::Display * display,EGLint * value) const484 egl::Error Surface::getUserWidth(const egl::Display *display, EGLint *value) const
485 {
486 if (mFixedSize)
487 {
488 *value = static_cast<EGLint>(mFixedWidth);
489 return NoError();
490 }
491 else
492 {
493 return mImplementation->getUserWidth(display, value);
494 }
495 }
496
getUserHeight(const egl::Display * display,EGLint * value) const497 egl::Error Surface::getUserHeight(const egl::Display *display, EGLint *value) const
498 {
499 if (mFixedSize)
500 {
501 *value = static_cast<EGLint>(mFixedHeight);
502 return NoError();
503 }
504 else
505 {
506 return mImplementation->getUserHeight(display, value);
507 }
508 }
509
bindTexImage(gl::Context * context,gl::Texture * texture,EGLint buffer)510 Error Surface::bindTexImage(gl::Context *context, gl::Texture *texture, EGLint buffer)
511 {
512 ASSERT(!mTexture);
513 ANGLE_TRY(mImplementation->bindTexImage(context, texture, buffer));
514
515 if (texture->bindTexImageFromSurface(context, this) == angle::Result::Stop)
516 {
517 return Error(EGL_BAD_SURFACE);
518 }
519 mTexture = texture;
520 mRefCount++;
521
522 return NoError();
523 }
524
releaseTexImage(const gl::Context * context,EGLint buffer)525 Error Surface::releaseTexImage(const gl::Context *context, EGLint buffer)
526 {
527 ASSERT(context);
528
529 ANGLE_TRY(mImplementation->releaseTexImage(context, buffer));
530
531 ASSERT(mTexture);
532 ANGLE_TRY(ResultToEGL(mTexture->releaseTexImageFromSurface(context)));
533
534 return releaseTexImageFromTexture(context);
535 }
536
getSyncValues(EGLuint64KHR * ust,EGLuint64KHR * msc,EGLuint64KHR * sbc)537 Error Surface::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc)
538 {
539 return mImplementation->getSyncValues(ust, msc, sbc);
540 }
541
getMscRate(EGLint * numerator,EGLint * denominator)542 Error Surface::getMscRate(EGLint *numerator, EGLint *denominator)
543 {
544 return mImplementation->getMscRate(numerator, denominator);
545 }
546
releaseTexImageFromTexture(const gl::Context * context)547 Error Surface::releaseTexImageFromTexture(const gl::Context *context)
548 {
549 ASSERT(mTexture);
550 mTexture = nullptr;
551 return releaseRef(context->getDisplay());
552 }
553
getAttachmentSize(const gl::ImageIndex &) const554 gl::Extents Surface::getAttachmentSize(const gl::ImageIndex & /*target*/) const
555 {
556 return gl::Extents(getWidth(), getHeight(), 1);
557 }
558
getAttachmentFormat(GLenum binding,const gl::ImageIndex & target) const559 gl::Format Surface::getAttachmentFormat(GLenum binding, const gl::ImageIndex &target) const
560 {
561 return (binding == GL_BACK ? mColorFormat : mDSFormat);
562 }
563
getAttachmentSamples(const gl::ImageIndex & target) const564 GLsizei Surface::getAttachmentSamples(const gl::ImageIndex &target) const
565 {
566 return getConfig()->samples;
567 }
568
isRenderable(const gl::Context * context,GLenum binding,const gl::ImageIndex & imageIndex) const569 bool Surface::isRenderable(const gl::Context *context,
570 GLenum binding,
571 const gl::ImageIndex &imageIndex) const
572 {
573 return true;
574 }
575
isYUV() const576 bool Surface::isYUV() const
577 {
578 // EGL_EXT_yuv_surface is not implemented.
579 return false;
580 }
581
getId() const582 GLuint Surface::getId() const
583 {
584 UNREACHABLE();
585 return 0;
586 }
587
getBufferAge(const gl::Context * context,EGLint * age) const588 Error Surface::getBufferAge(const gl::Context *context, EGLint *age) const
589 {
590 // When EGL_BUFFER_PRESERVED, the previous frame contents are copied to
591 // current frame, so the buffer age is always 1.
592 if (mSwapBehavior == EGL_BUFFER_PRESERVED)
593 {
594 if (age != nullptr)
595 {
596 *age = 1;
597 }
598 return egl::NoError();
599 }
600 return mImplementation->getBufferAge(context, age);
601 }
602
createDefaultFramebuffer(const gl::Context * context,egl::Surface * readSurface)603 gl::Framebuffer *Surface::createDefaultFramebuffer(const gl::Context *context,
604 egl::Surface *readSurface)
605 {
606 return new gl::Framebuffer(context, this, readSurface);
607 }
608
initState(const gl::ImageIndex &) const609 gl::InitState Surface::initState(const gl::ImageIndex & /*imageIndex*/) const
610 {
611 return mInitState;
612 }
613
setInitState(const gl::ImageIndex &,gl::InitState initState)614 void Surface::setInitState(const gl::ImageIndex & /*imageIndex*/, gl::InitState initState)
615 {
616 mInitState = initState;
617 }
618
setTimestampsEnabled(bool enabled)619 void Surface::setTimestampsEnabled(bool enabled)
620 {
621 mImplementation->setTimestampsEnabled(enabled);
622 mState.timestampsEnabled = enabled;
623 }
624
isTimestampsEnabled() const625 bool Surface::isTimestampsEnabled() const
626 {
627 return mState.timestampsEnabled;
628 }
629
getSupportedCompositorTimings() const630 const SupportedCompositorTiming &Surface::getSupportedCompositorTimings() const
631 {
632 return mState.supportedCompositorTimings;
633 }
634
getCompositorTiming(EGLint numTimestamps,const EGLint * names,EGLnsecsANDROID * values) const635 Error Surface::getCompositorTiming(EGLint numTimestamps,
636 const EGLint *names,
637 EGLnsecsANDROID *values) const
638 {
639 return mImplementation->getCompositorTiming(numTimestamps, names, values);
640 }
641
getNextFrameId(EGLuint64KHR * frameId) const642 Error Surface::getNextFrameId(EGLuint64KHR *frameId) const
643 {
644 return mImplementation->getNextFrameId(frameId);
645 }
646
getSupportedTimestamps() const647 const SupportedTimestamps &Surface::getSupportedTimestamps() const
648 {
649 return mState.supportedTimestamps;
650 }
651
getFrameTimestamps(EGLuint64KHR frameId,EGLint numTimestamps,const EGLint * timestamps,EGLnsecsANDROID * values) const652 Error Surface::getFrameTimestamps(EGLuint64KHR frameId,
653 EGLint numTimestamps,
654 const EGLint *timestamps,
655 EGLnsecsANDROID *values) const
656 {
657 return mImplementation->getFrameTimestamps(frameId, numTimestamps, timestamps, values);
658 }
659
onSubjectStateChange(angle::SubjectIndex index,angle::SubjectMessage message)660 void Surface::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
661 {
662 ASSERT(index == kSurfaceImplSubjectIndex);
663 switch (message)
664 {
665 case angle::SubjectMessage::SubjectChanged:
666 onStateChange(angle::SubjectMessage::ContentsChanged);
667 break;
668 case angle::SubjectMessage::SurfaceChanged:
669 onStateChange(angle::SubjectMessage::SurfaceChanged);
670 break;
671 default:
672 UNREACHABLE();
673 break;
674 }
675 }
676
WindowSurface(rx::EGLImplFactory * implFactory,const egl::Config * config,EGLNativeWindowType window,const AttributeMap & attribs)677 WindowSurface::WindowSurface(rx::EGLImplFactory *implFactory,
678 const egl::Config *config,
679 EGLNativeWindowType window,
680 const AttributeMap &attribs)
681 : Surface(EGL_WINDOW_BIT, config, attribs)
682 {
683 mImplementation = implFactory->createWindowSurface(mState, window, attribs);
684 }
685
~WindowSurface()686 WindowSurface::~WindowSurface() {}
687
PbufferSurface(rx::EGLImplFactory * implFactory,const Config * config,const AttributeMap & attribs)688 PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory,
689 const Config *config,
690 const AttributeMap &attribs)
691 : Surface(EGL_PBUFFER_BIT, config, attribs)
692 {
693 mImplementation = implFactory->createPbufferSurface(mState, attribs);
694 }
695
PbufferSurface(rx::EGLImplFactory * implFactory,const Config * config,EGLenum buftype,EGLClientBuffer clientBuffer,const AttributeMap & attribs)696 PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory,
697 const Config *config,
698 EGLenum buftype,
699 EGLClientBuffer clientBuffer,
700 const AttributeMap &attribs)
701 : Surface(EGL_PBUFFER_BIT, config, attribs, buftype)
702 {
703 mImplementation =
704 implFactory->createPbufferFromClientBuffer(mState, buftype, clientBuffer, attribs);
705 }
706
~PbufferSurface()707 PbufferSurface::~PbufferSurface() {}
708
PixmapSurface(rx::EGLImplFactory * implFactory,const Config * config,NativePixmapType nativePixmap,const AttributeMap & attribs)709 PixmapSurface::PixmapSurface(rx::EGLImplFactory *implFactory,
710 const Config *config,
711 NativePixmapType nativePixmap,
712 const AttributeMap &attribs)
713 : Surface(EGL_PIXMAP_BIT, config, attribs)
714 {
715 mImplementation = implFactory->createPixmapSurface(mState, nativePixmap, attribs);
716 }
717
~PixmapSurface()718 PixmapSurface::~PixmapSurface() {}
719
720 // SurfaceDeleter implementation.
721
SurfaceDeleter(const Display * display)722 SurfaceDeleter::SurfaceDeleter(const Display *display) : mDisplay(display) {}
723
~SurfaceDeleter()724 SurfaceDeleter::~SurfaceDeleter() {}
725
operator ()(Surface * surface)726 void SurfaceDeleter::operator()(Surface *surface)
727 {
728 ANGLE_SWALLOW_ERR(surface->onDestroy(mDisplay));
729 }
730
731 } // namespace egl
732