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