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 
hasProtectedContent() const51 bool SurfaceState::hasProtectedContent() const
52 {
53     return attributes.get(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) == EGL_TRUE;
54 }
55 
Surface(EGLint surfaceType,const egl::Config * config,const AttributeMap & attributes,bool forceRobustResourceInit,EGLenum buftype)56 Surface::Surface(EGLint surfaceType,
57                  const egl::Config *config,
58                  const AttributeMap &attributes,
59                  bool forceRobustResourceInit,
60                  EGLenum buftype)
61     : FramebufferAttachmentObject(),
62       mState(config, attributes),
63       mImplementation(nullptr),
64       mRefCount(0),
65       mDestroyed(false),
66       mType(surfaceType),
67       mBuftype(buftype),
68       mPostSubBufferRequested(false),
69       mLargestPbuffer(false),
70       mGLColorspace(EGL_GL_COLORSPACE_LINEAR),
71       mVGAlphaFormat(EGL_VG_ALPHA_FORMAT_NONPRE),
72       mVGColorspace(EGL_VG_COLORSPACE_sRGB),
73       mMipmapTexture(false),
74       mMipmapLevel(0),
75       mHorizontalResolution(EGL_UNKNOWN),
76       mVerticalResolution(EGL_UNKNOWN),
77       mMultisampleResolve(EGL_MULTISAMPLE_RESOLVE_DEFAULT),
78       mFixedSize(false),
79       mFixedWidth(0),
80       mFixedHeight(0),
81       mTextureFormat(TextureFormat::NoTexture),
82       mTextureTarget(EGL_NO_TEXTURE),
83       // FIXME: Determine actual pixel aspect ratio
84       mPixelAspectRatio(static_cast<EGLint>(1.0 * EGL_DISPLAY_SCALING)),
85       mRenderBuffer(EGL_BACK_BUFFER),
86       mSwapBehavior(EGL_NONE),
87       mOrientation(0),
88       mTexture(nullptr),
89       mColorFormat(config->renderTargetFormat),
90       mDSFormat(config->depthStencilFormat),
91       mInitState(gl::InitState::Initialized),
92       mImplObserverBinding(this, kSurfaceImplSubjectIndex)
93 {
94     mPostSubBufferRequested =
95         (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE);
96     mFlexibleSurfaceCompatibilityRequested =
97         (attributes.get(EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, EGL_FALSE) == EGL_TRUE);
98 
99     if (mType == EGL_PBUFFER_BIT)
100     {
101         mLargestPbuffer = (attributes.get(EGL_LARGEST_PBUFFER, EGL_FALSE) == EGL_TRUE);
102     }
103 
104     if (mType == EGL_PIXMAP_BIT)
105     {
106         mRenderBuffer = EGL_SINGLE_BUFFER;
107     }
108 
109     mGLColorspace =
110         static_cast<EGLenum>(attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR));
111     mVGAlphaFormat =
112         static_cast<EGLenum>(attributes.get(EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_NONPRE));
113     mVGColorspace = static_cast<EGLenum>(attributes.get(EGL_VG_COLORSPACE, EGL_VG_COLORSPACE_sRGB));
114     mMipmapTexture = (attributes.get(EGL_MIPMAP_TEXTURE, EGL_FALSE) == EGL_TRUE);
115 
116     mRobustResourceInitialization =
117         forceRobustResourceInit ||
118         (attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
119     if (mRobustResourceInitialization)
120     {
121         mInitState = gl::InitState::MayNeedInit;
122     }
123 
124     mFixedSize = (attributes.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE);
125     if (mFixedSize)
126     {
127         mFixedWidth  = static_cast<size_t>(attributes.get(EGL_WIDTH, 0));
128         mFixedHeight = static_cast<size_t>(attributes.get(EGL_HEIGHT, 0));
129     }
130 
131     if (mType != EGL_WINDOW_BIT)
132     {
133         mTextureFormat = attributes.getAsPackedEnum(EGL_TEXTURE_FORMAT, TextureFormat::NoTexture);
134         mTextureTarget = static_cast<EGLenum>(attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE));
135     }
136 
137     mOrientation = static_cast<EGLint>(attributes.get(EGL_SURFACE_ORIENTATION_ANGLE, 0));
138 
139     mTextureOffset.x = static_cast<int>(mState.attributes.get(EGL_TEXTURE_OFFSET_X_ANGLE, 0));
140     mTextureOffset.y = static_cast<int>(mState.attributes.get(EGL_TEXTURE_OFFSET_Y_ANGLE, 0));
141 }
142 
~Surface()143 Surface::~Surface() {}
144 
getAttachmentImpl() const145 rx::FramebufferAttachmentObjectImpl *Surface::getAttachmentImpl() const
146 {
147     return mImplementation;
148 }
149 
destroyImpl(const Display * display)150 Error Surface::destroyImpl(const Display *display)
151 {
152     if (mImplementation)
153     {
154         mImplementation->destroy(display);
155     }
156 
157     ASSERT(!mTexture);
158 
159     SafeDelete(mImplementation);
160 
161     delete this;
162     return NoError();
163 }
164 
postSwap(const gl::Context * context)165 void Surface::postSwap(const gl::Context *context)
166 {
167     if (mRobustResourceInitialization && mSwapBehavior != EGL_BUFFER_PRESERVED)
168     {
169         mInitState = gl::InitState::MayNeedInit;
170         onStateChange(angle::SubjectMessage::SubjectChanged);
171     }
172 }
173 
initialize(const Display * display)174 Error Surface::initialize(const Display *display)
175 {
176     GLenum overrideRenderTargetFormat = mState.config->renderTargetFormat;
177 
178     // To account for color space differences, override the renderTargetFormat with the
179     // non-linear format. If no suitable non-linear format was found, return
180     // EGL_BAD_MATCH error
181     if (!gl::ColorspaceFormatOverride(mGLColorspace, &overrideRenderTargetFormat))
182     {
183         return egl::EglBadMatch();
184     }
185 
186     // If an override is required update mState.config as well
187     if (mState.config->renderTargetFormat != overrideRenderTargetFormat)
188     {
189         egl::Config *overrideConfig        = new egl::Config(*(mState.config));
190         overrideConfig->renderTargetFormat = overrideRenderTargetFormat;
191         delete mState.config;
192         mState.config = overrideConfig;
193 
194         mColorFormat = gl::Format(mState.config->renderTargetFormat);
195         mDSFormat    = gl::Format(mState.config->depthStencilFormat);
196     }
197 
198     ANGLE_TRY(mImplementation->initialize(display));
199 
200     // Initialized here since impl is nullptr in the constructor.
201     // Must happen after implementation initialize for Android.
202     mSwapBehavior = mImplementation->getSwapBehavior();
203 
204     if (mBuftype == EGL_IOSURFACE_ANGLE)
205     {
206         GLenum internalFormat =
207             static_cast<GLenum>(mState.attributes.get(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE));
208         GLenum type = static_cast<GLenum>(mState.attributes.get(EGL_TEXTURE_TYPE_ANGLE));
209 
210         // GL_RGBA + GL_HALF_FLOAT is not a valid format/type combination in GLES like it is in
211         // desktop GL. Adjust the frontend format to be sized RGBA16F.
212         if (internalFormat == GL_RGBA && type == GL_HALF_FLOAT)
213         {
214             internalFormat = GL_RGBA16F;
215         }
216         mColorFormat = gl::Format(internalFormat, type);
217     }
218     if (mBuftype == EGL_D3D_TEXTURE_ANGLE)
219     {
220         const angle::Format *colorFormat = mImplementation->getD3DTextureColorFormat();
221         ASSERT(colorFormat != nullptr);
222         GLenum internalFormat = colorFormat->fboImplementationInternalFormat;
223         mColorFormat          = gl::Format(internalFormat, colorFormat->componentType);
224         mGLColorspace         = EGL_GL_COLORSPACE_LINEAR;
225         if (mColorFormat.info->colorEncoding == GL_SRGB)
226         {
227             mGLColorspace = EGL_GL_COLORSPACE_SRGB;
228         }
229     }
230 
231     if (mType == EGL_WINDOW_BIT && display->getExtensions().getFrameTimestamps)
232     {
233         mState.supportedCompositorTimings = mImplementation->getSupportedCompositorTimings();
234         mState.supportedTimestamps        = mImplementation->getSupportedTimestamps();
235     }
236 
237     mImplObserverBinding.bind(mImplementation);
238 
239     return NoError();
240 }
241 
makeCurrent(const gl::Context * context)242 Error Surface::makeCurrent(const gl::Context *context)
243 {
244     ANGLE_TRY(mImplementation->makeCurrent(context));
245 
246     mRefCount++;
247     return NoError();
248 }
249 
unMakeCurrent(const gl::Context * context)250 Error Surface::unMakeCurrent(const gl::Context *context)
251 {
252     ANGLE_TRY(mImplementation->unMakeCurrent(context));
253     return releaseRef(context->getDisplay());
254 }
255 
releaseRef(const Display * display)256 Error Surface::releaseRef(const Display *display)
257 {
258     ASSERT(mRefCount > 0);
259     mRefCount--;
260     if (mRefCount == 0 && mDestroyed)
261     {
262         ASSERT(display);
263         return destroyImpl(display);
264     }
265 
266     return NoError();
267 }
268 
onDestroy(const Display * display)269 Error Surface::onDestroy(const Display *display)
270 {
271     mDestroyed = true;
272     if (mRefCount == 0)
273     {
274         return destroyImpl(display);
275     }
276     return NoError();
277 }
278 
setLabel(EGLLabelKHR label)279 void Surface::setLabel(EGLLabelKHR label)
280 {
281     mState.label = label;
282 }
283 
getLabel() const284 EGLLabelKHR Surface::getLabel() const
285 {
286     return mState.label;
287 }
288 
getType() const289 EGLint Surface::getType() const
290 {
291     return mType;
292 }
293 
swap(const gl::Context * context)294 Error Surface::swap(const gl::Context *context)
295 {
296     ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swap");
297     context->onPreSwap();
298 
299     context->getState().getOverlay()->onSwap();
300 
301     ANGLE_TRY(mImplementation->swap(context));
302     postSwap(context);
303     return NoError();
304 }
305 
swapWithDamage(const gl::Context * context,const EGLint * rects,EGLint n_rects)306 Error Surface::swapWithDamage(const gl::Context *context, const EGLint *rects, EGLint n_rects)
307 {
308     ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swapWithDamage");
309     context->onPreSwap();
310 
311     context->getState().getOverlay()->onSwap();
312 
313     ANGLE_TRY(mImplementation->swapWithDamage(context, rects, n_rects));
314     postSwap(context);
315     return NoError();
316 }
317 
swapWithFrameToken(const gl::Context * context,EGLFrameTokenANGLE frameToken)318 Error Surface::swapWithFrameToken(const gl::Context *context, EGLFrameTokenANGLE frameToken)
319 {
320     ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swapWithFrameToken");
321     context->onPreSwap();
322 
323     context->getState().getOverlay()->onSwap();
324 
325     ANGLE_TRY(mImplementation->swapWithFrameToken(context, frameToken));
326     postSwap(context);
327     return NoError();
328 }
329 
postSubBuffer(const gl::Context * context,EGLint x,EGLint y,EGLint width,EGLint height)330 Error Surface::postSubBuffer(const gl::Context *context,
331                              EGLint x,
332                              EGLint y,
333                              EGLint width,
334                              EGLint height)
335 {
336     if (width == 0 || height == 0)
337     {
338         return egl::NoError();
339     }
340 
341     context->getState().getOverlay()->onSwap();
342 
343     ANGLE_TRY(mImplementation->postSubBuffer(context, x, y, width, height));
344     postSwap(context);
345     return NoError();
346 }
347 
setPresentationTime(EGLnsecsANDROID time)348 Error Surface::setPresentationTime(EGLnsecsANDROID time)
349 {
350     return mImplementation->setPresentationTime(time);
351 }
352 
querySurfacePointerANGLE(EGLint attribute,void ** value)353 Error Surface::querySurfacePointerANGLE(EGLint attribute, void **value)
354 {
355     return mImplementation->querySurfacePointerANGLE(attribute, value);
356 }
357 
isPostSubBufferSupported() const358 EGLint Surface::isPostSubBufferSupported() const
359 {
360     return mPostSubBufferRequested && mImplementation->isPostSubBufferSupported();
361 }
362 
setSwapInterval(EGLint interval)363 void Surface::setSwapInterval(EGLint interval)
364 {
365     mImplementation->setSwapInterval(interval);
366 }
367 
setMipmapLevel(EGLint level)368 void Surface::setMipmapLevel(EGLint level)
369 {
370     // Level is set but ignored
371     UNIMPLEMENTED();
372     mMipmapLevel = level;
373 }
374 
setMultisampleResolve(EGLenum resolve)375 void Surface::setMultisampleResolve(EGLenum resolve)
376 {
377     // Behaviour is set but ignored
378     UNIMPLEMENTED();
379     mMultisampleResolve = resolve;
380 }
381 
setSwapBehavior(EGLenum behavior)382 void Surface::setSwapBehavior(EGLenum behavior)
383 {
384     // Behaviour is set but ignored
385     UNIMPLEMENTED();
386     mSwapBehavior = behavior;
387 }
388 
setFixedWidth(EGLint width)389 void Surface::setFixedWidth(EGLint width)
390 {
391     mFixedWidth = width;
392     mImplementation->setFixedWidth(width);
393 }
394 
setFixedHeight(EGLint height)395 void Surface::setFixedHeight(EGLint height)
396 {
397     mFixedHeight = height;
398     mImplementation->setFixedHeight(height);
399 }
400 
getConfig() const401 const Config *Surface::getConfig() const
402 {
403     return mState.config;
404 }
405 
getPixelAspectRatio() const406 EGLint Surface::getPixelAspectRatio() const
407 {
408     return mPixelAspectRatio;
409 }
410 
getRenderBuffer() const411 EGLenum Surface::getRenderBuffer() const
412 {
413     return mRenderBuffer;
414 }
415 
getSwapBehavior() const416 EGLenum Surface::getSwapBehavior() const
417 {
418     return mSwapBehavior;
419 }
420 
getTextureFormat() const421 TextureFormat Surface::getTextureFormat() const
422 {
423     return mTextureFormat;
424 }
425 
getTextureTarget() const426 EGLenum Surface::getTextureTarget() const
427 {
428     return mTextureTarget;
429 }
430 
getLargestPbuffer() const431 bool Surface::getLargestPbuffer() const
432 {
433     return mLargestPbuffer;
434 }
435 
getGLColorspace() const436 EGLenum Surface::getGLColorspace() const
437 {
438     return mGLColorspace;
439 }
440 
getVGAlphaFormat() const441 EGLenum Surface::getVGAlphaFormat() const
442 {
443     return mVGAlphaFormat;
444 }
445 
getVGColorspace() const446 EGLenum Surface::getVGColorspace() const
447 {
448     return mVGColorspace;
449 }
450 
getMipmapTexture() const451 bool Surface::getMipmapTexture() const
452 {
453     return mMipmapTexture;
454 }
455 
getMipmapLevel() const456 EGLint Surface::getMipmapLevel() const
457 {
458     return mMipmapLevel;
459 }
460 
getHorizontalResolution() const461 EGLint Surface::getHorizontalResolution() const
462 {
463     return mHorizontalResolution;
464 }
465 
getVerticalResolution() const466 EGLint Surface::getVerticalResolution() const
467 {
468     return mVerticalResolution;
469 }
470 
getMultisampleResolve() const471 EGLenum Surface::getMultisampleResolve() const
472 {
473     return mMultisampleResolve;
474 }
475 
isFixedSize() const476 EGLint Surface::isFixedSize() const
477 {
478     return mFixedSize;
479 }
480 
getWidth() const481 EGLint Surface::getWidth() const
482 {
483     return mFixedSize ? static_cast<EGLint>(mFixedWidth) : mImplementation->getWidth();
484 }
485 
getHeight() const486 EGLint Surface::getHeight() const
487 {
488     return mFixedSize ? static_cast<EGLint>(mFixedHeight) : mImplementation->getHeight();
489 }
490 
getUserWidth(const egl::Display * display,EGLint * value) const491 egl::Error Surface::getUserWidth(const egl::Display *display, EGLint *value) const
492 {
493     if (mFixedSize)
494     {
495         *value = static_cast<EGLint>(mFixedWidth);
496         return NoError();
497     }
498     else
499     {
500         return mImplementation->getUserWidth(display, value);
501     }
502 }
503 
getUserHeight(const egl::Display * display,EGLint * value) const504 egl::Error Surface::getUserHeight(const egl::Display *display, EGLint *value) const
505 {
506     if (mFixedSize)
507     {
508         *value = static_cast<EGLint>(mFixedHeight);
509         return NoError();
510     }
511     else
512     {
513         return mImplementation->getUserHeight(display, value);
514     }
515 }
516 
bindTexImage(gl::Context * context,gl::Texture * texture,EGLint buffer)517 Error Surface::bindTexImage(gl::Context *context, gl::Texture *texture, EGLint buffer)
518 {
519     ASSERT(!mTexture);
520     ANGLE_TRY(mImplementation->bindTexImage(context, texture, buffer));
521 
522     if (texture->bindTexImageFromSurface(context, this) == angle::Result::Stop)
523     {
524         return Error(EGL_BAD_SURFACE);
525     }
526     mTexture = texture;
527     mRefCount++;
528 
529     return NoError();
530 }
531 
releaseTexImage(const gl::Context * context,EGLint buffer)532 Error Surface::releaseTexImage(const gl::Context *context, EGLint buffer)
533 {
534     ASSERT(context);
535 
536     ANGLE_TRY(mImplementation->releaseTexImage(context, buffer));
537 
538     ASSERT(mTexture);
539     ANGLE_TRY(ResultToEGL(mTexture->releaseTexImageFromSurface(context)));
540 
541     return releaseTexImageFromTexture(context);
542 }
543 
getSyncValues(EGLuint64KHR * ust,EGLuint64KHR * msc,EGLuint64KHR * sbc)544 Error Surface::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc)
545 {
546     return mImplementation->getSyncValues(ust, msc, sbc);
547 }
548 
getMscRate(EGLint * numerator,EGLint * denominator)549 Error Surface::getMscRate(EGLint *numerator, EGLint *denominator)
550 {
551     return mImplementation->getMscRate(numerator, denominator);
552 }
553 
releaseTexImageFromTexture(const gl::Context * context)554 Error Surface::releaseTexImageFromTexture(const gl::Context *context)
555 {
556     ASSERT(mTexture);
557     mTexture = nullptr;
558     return releaseRef(context->getDisplay());
559 }
560 
getAttachmentSize(const gl::ImageIndex &) const561 gl::Extents Surface::getAttachmentSize(const gl::ImageIndex & /*target*/) const
562 {
563     return gl::Extents(getWidth(), getHeight(), 1);
564 }
565 
getAttachmentFormat(GLenum binding,const gl::ImageIndex & target) const566 gl::Format Surface::getAttachmentFormat(GLenum binding, const gl::ImageIndex &target) const
567 {
568     return (binding == GL_BACK ? mColorFormat : mDSFormat);
569 }
570 
getAttachmentSamples(const gl::ImageIndex & target) const571 GLsizei Surface::getAttachmentSamples(const gl::ImageIndex &target) const
572 {
573     return getConfig()->samples;
574 }
575 
isRenderable(const gl::Context * context,GLenum binding,const gl::ImageIndex & imageIndex) const576 bool Surface::isRenderable(const gl::Context *context,
577                            GLenum binding,
578                            const gl::ImageIndex &imageIndex) const
579 {
580     return true;
581 }
582 
isYUV() const583 bool Surface::isYUV() const
584 {
585     // EGL_EXT_yuv_surface is not implemented.
586     return false;
587 }
588 
getId() const589 GLuint Surface::getId() const
590 {
591     UNREACHABLE();
592     return 0;
593 }
594 
getBufferAge(const gl::Context * context,EGLint * age) const595 Error Surface::getBufferAge(const gl::Context *context, EGLint *age) const
596 {
597     // When EGL_BUFFER_PRESERVED, the previous frame contents are copied to
598     // current frame, so the buffer age is always 1.
599     if (mSwapBehavior == EGL_BUFFER_PRESERVED)
600     {
601         if (age != nullptr)
602         {
603             *age = 1;
604         }
605         return egl::NoError();
606     }
607     return mImplementation->getBufferAge(context, age);
608 }
609 
createDefaultFramebuffer(const gl::Context * context,egl::Surface * readSurface)610 gl::Framebuffer *Surface::createDefaultFramebuffer(const gl::Context *context,
611                                                    egl::Surface *readSurface)
612 {
613     return new gl::Framebuffer(context, this, readSurface);
614 }
615 
initState(const gl::ImageIndex &) const616 gl::InitState Surface::initState(const gl::ImageIndex & /*imageIndex*/) const
617 {
618     return mInitState;
619 }
620 
setInitState(const gl::ImageIndex &,gl::InitState initState)621 void Surface::setInitState(const gl::ImageIndex & /*imageIndex*/, gl::InitState initState)
622 {
623     mInitState = initState;
624 }
625 
setTimestampsEnabled(bool enabled)626 void Surface::setTimestampsEnabled(bool enabled)
627 {
628     mImplementation->setTimestampsEnabled(enabled);
629     mState.timestampsEnabled = enabled;
630 }
631 
isTimestampsEnabled() const632 bool Surface::isTimestampsEnabled() const
633 {
634     return mState.timestampsEnabled;
635 }
636 
hasProtectedContent() const637 bool Surface::hasProtectedContent() const
638 {
639     return mState.hasProtectedContent();
640 }
641 
getSupportedCompositorTimings() const642 const SupportedCompositorTiming &Surface::getSupportedCompositorTimings() const
643 {
644     return mState.supportedCompositorTimings;
645 }
646 
getCompositorTiming(EGLint numTimestamps,const EGLint * names,EGLnsecsANDROID * values) const647 Error Surface::getCompositorTiming(EGLint numTimestamps,
648                                    const EGLint *names,
649                                    EGLnsecsANDROID *values) const
650 {
651     return mImplementation->getCompositorTiming(numTimestamps, names, values);
652 }
653 
getNextFrameId(EGLuint64KHR * frameId) const654 Error Surface::getNextFrameId(EGLuint64KHR *frameId) const
655 {
656     return mImplementation->getNextFrameId(frameId);
657 }
658 
getSupportedTimestamps() const659 const SupportedTimestamps &Surface::getSupportedTimestamps() const
660 {
661     return mState.supportedTimestamps;
662 }
663 
getFrameTimestamps(EGLuint64KHR frameId,EGLint numTimestamps,const EGLint * timestamps,EGLnsecsANDROID * values) const664 Error Surface::getFrameTimestamps(EGLuint64KHR frameId,
665                                   EGLint numTimestamps,
666                                   const EGLint *timestamps,
667                                   EGLnsecsANDROID *values) const
668 {
669     return mImplementation->getFrameTimestamps(frameId, numTimestamps, timestamps, values);
670 }
671 
onSubjectStateChange(angle::SubjectIndex index,angle::SubjectMessage message)672 void Surface::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
673 {
674     ASSERT(index == kSurfaceImplSubjectIndex);
675     switch (message)
676     {
677         case angle::SubjectMessage::SubjectChanged:
678             onStateChange(angle::SubjectMessage::ContentsChanged);
679             break;
680         case angle::SubjectMessage::SurfaceChanged:
681             onStateChange(angle::SubjectMessage::SurfaceChanged);
682             break;
683         default:
684             UNREACHABLE();
685             break;
686     }
687 }
688 
setRenderBuffer(EGLint value)689 void Surface::setRenderBuffer(EGLint value)
690 {
691     mRenderBuffer = value;
692 }
693 
WindowSurface(rx::EGLImplFactory * implFactory,const egl::Config * config,EGLNativeWindowType window,const AttributeMap & attribs,bool robustResourceInit)694 WindowSurface::WindowSurface(rx::EGLImplFactory *implFactory,
695                              const egl::Config *config,
696                              EGLNativeWindowType window,
697                              const AttributeMap &attribs,
698                              bool robustResourceInit)
699     : Surface(EGL_WINDOW_BIT, config, attribs, robustResourceInit)
700 {
701     mImplementation = implFactory->createWindowSurface(mState, window, attribs);
702 }
703 
~WindowSurface()704 WindowSurface::~WindowSurface() {}
705 
PbufferSurface(rx::EGLImplFactory * implFactory,const Config * config,const AttributeMap & attribs,bool robustResourceInit)706 PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory,
707                                const Config *config,
708                                const AttributeMap &attribs,
709                                bool robustResourceInit)
710     : Surface(EGL_PBUFFER_BIT, config, attribs, robustResourceInit)
711 {
712     mImplementation = implFactory->createPbufferSurface(mState, attribs);
713 }
714 
PbufferSurface(rx::EGLImplFactory * implFactory,const Config * config,EGLenum buftype,EGLClientBuffer clientBuffer,const AttributeMap & attribs,bool robustResourceInit)715 PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory,
716                                const Config *config,
717                                EGLenum buftype,
718                                EGLClientBuffer clientBuffer,
719                                const AttributeMap &attribs,
720                                bool robustResourceInit)
721     : Surface(EGL_PBUFFER_BIT, config, attribs, robustResourceInit, buftype)
722 {
723     mImplementation =
724         implFactory->createPbufferFromClientBuffer(mState, buftype, clientBuffer, attribs);
725 }
726 
~PbufferSurface()727 PbufferSurface::~PbufferSurface() {}
728 
PixmapSurface(rx::EGLImplFactory * implFactory,const Config * config,NativePixmapType nativePixmap,const AttributeMap & attribs,bool robustResourceInit)729 PixmapSurface::PixmapSurface(rx::EGLImplFactory *implFactory,
730                              const Config *config,
731                              NativePixmapType nativePixmap,
732                              const AttributeMap &attribs,
733                              bool robustResourceInit)
734     : Surface(EGL_PIXMAP_BIT, config, attribs, robustResourceInit)
735 {
736     mImplementation = implFactory->createPixmapSurface(mState, nativePixmap, attribs);
737 }
738 
~PixmapSurface()739 PixmapSurface::~PixmapSurface() {}
740 
741 // SurfaceDeleter implementation.
742 
SurfaceDeleter(const Display * display)743 SurfaceDeleter::SurfaceDeleter(const Display *display) : mDisplay(display) {}
744 
~SurfaceDeleter()745 SurfaceDeleter::~SurfaceDeleter() {}
746 
operator ()(Surface * surface)747 void SurfaceDeleter::operator()(Surface *surface)
748 {
749     ANGLE_SWALLOW_ERR(surface->onDestroy(mDisplay));
750 }
751 
752 }  // namespace egl
753