• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getPreferredSwapInterval() const56 EGLint SurfaceState::getPreferredSwapInterval() const
57 {
58     return attributes.getAsInt(EGL_SWAP_INTERVAL_ANGLE, 1);
59 }
60 
Surface(EGLint surfaceType,const egl::Config * config,const AttributeMap & attributes,bool forceRobustResourceInit,EGLenum buftype)61 Surface::Surface(EGLint surfaceType,
62                  const egl::Config *config,
63                  const AttributeMap &attributes,
64                  bool forceRobustResourceInit,
65                  EGLenum buftype)
66     : FramebufferAttachmentObject(),
67       mState(config, attributes),
68       mImplementation(nullptr),
69       mRefCount(0),
70       mDestroyed(false),
71       mType(surfaceType),
72       mBuftype(buftype),
73       mPostSubBufferRequested(false),
74       mLargestPbuffer(false),
75       mGLColorspace(EGL_GL_COLORSPACE_LINEAR),
76       mVGAlphaFormat(EGL_VG_ALPHA_FORMAT_NONPRE),
77       mVGColorspace(EGL_VG_COLORSPACE_sRGB),
78       mMipmapTexture(false),
79       mMipmapLevel(0),
80       mHorizontalResolution(EGL_UNKNOWN),
81       mVerticalResolution(EGL_UNKNOWN),
82       mMultisampleResolve(EGL_MULTISAMPLE_RESOLVE_DEFAULT),
83       mFixedSize(false),
84       mFixedWidth(0),
85       mFixedHeight(0),
86       mTextureFormat(TextureFormat::NoTexture),
87       mTextureTarget(EGL_NO_TEXTURE),
88       // FIXME: Determine actual pixel aspect ratio
89       mPixelAspectRatio(static_cast<EGLint>(1.0 * EGL_DISPLAY_SCALING)),
90       mRenderBuffer(EGL_BACK_BUFFER),
91       mSwapBehavior(EGL_NONE),
92       mOrientation(0),
93       mTexture(nullptr),
94       mColorFormat(config->renderTargetFormat),
95       mDSFormat(config->depthStencilFormat),
96       mIsCurrentOnAnyContext(false),
97       mLockBufferPtr(nullptr),
98       mLockBufferPitch(0),
99       mInitState(gl::InitState::Initialized),
100       mImplObserverBinding(this, kSurfaceImplSubjectIndex)
101 {
102     mPostSubBufferRequested =
103         (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE);
104 
105     if (mType == EGL_PBUFFER_BIT)
106     {
107         mLargestPbuffer = (attributes.get(EGL_LARGEST_PBUFFER, EGL_FALSE) == EGL_TRUE);
108     }
109 
110     if (mType == EGL_PIXMAP_BIT)
111     {
112         mRenderBuffer = EGL_SINGLE_BUFFER;
113     }
114 
115     mGLColorspace =
116         static_cast<EGLenum>(attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR));
117     mVGAlphaFormat =
118         static_cast<EGLenum>(attributes.get(EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_NONPRE));
119     mVGColorspace = static_cast<EGLenum>(attributes.get(EGL_VG_COLORSPACE, EGL_VG_COLORSPACE_sRGB));
120     mMipmapTexture = (attributes.get(EGL_MIPMAP_TEXTURE, EGL_FALSE) == EGL_TRUE);
121 
122     mRobustResourceInitialization =
123         forceRobustResourceInit ||
124         (attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
125     if (mRobustResourceInitialization)
126     {
127         mInitState = gl::InitState::MayNeedInit;
128     }
129 
130     mFixedSize = (attributes.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE);
131     if (mFixedSize)
132     {
133         mFixedWidth  = static_cast<size_t>(attributes.get(EGL_WIDTH, 0));
134         mFixedHeight = static_cast<size_t>(attributes.get(EGL_HEIGHT, 0));
135     }
136 
137     if (mType != EGL_WINDOW_BIT)
138     {
139         mTextureFormat = attributes.getAsPackedEnum(EGL_TEXTURE_FORMAT, TextureFormat::NoTexture);
140         mTextureTarget = static_cast<EGLenum>(attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE));
141     }
142 
143     mOrientation = static_cast<EGLint>(attributes.get(EGL_SURFACE_ORIENTATION_ANGLE, 0));
144 
145     mTextureOffset.x = static_cast<int>(mState.attributes.get(EGL_TEXTURE_OFFSET_X_ANGLE, 0));
146     mTextureOffset.y = static_cast<int>(mState.attributes.get(EGL_TEXTURE_OFFSET_Y_ANGLE, 0));
147 }
148 
~Surface()149 Surface::~Surface() {}
150 
getAttachmentImpl() const151 rx::FramebufferAttachmentObjectImpl *Surface::getAttachmentImpl() const
152 {
153     return mImplementation;
154 }
155 
destroyImpl(const Display * display)156 Error Surface::destroyImpl(const Display *display)
157 {
158     if (mImplementation)
159     {
160         mImplementation->destroy(display);
161     }
162 
163     ASSERT(!mTexture);
164 
165     SafeDelete(mImplementation);
166 
167     delete this;
168     return NoError();
169 }
170 
postSwap(const gl::Context * context)171 void Surface::postSwap(const gl::Context *context)
172 {
173     if (mRobustResourceInitialization && mSwapBehavior != EGL_BUFFER_PRESERVED)
174     {
175         mInitState = gl::InitState::MayNeedInit;
176         onStateChange(angle::SubjectMessage::SubjectChanged);
177     }
178 }
179 
initialize(const Display * display)180 Error Surface::initialize(const Display *display)
181 {
182     GLenum overrideRenderTargetFormat = mState.config->renderTargetFormat;
183 
184     // To account for color space differences, override the renderTargetFormat with the
185     // non-linear format. If no suitable non-linear format was found, return
186     // EGL_BAD_MATCH error
187     if (!gl::ColorspaceFormatOverride(mGLColorspace, &overrideRenderTargetFormat))
188     {
189         return egl::EglBadMatch();
190     }
191 
192     // If an override is required update mState.config as well
193     if (mState.config->renderTargetFormat != overrideRenderTargetFormat)
194     {
195         egl::Config *overrideConfig        = new egl::Config(*(mState.config));
196         overrideConfig->renderTargetFormat = overrideRenderTargetFormat;
197         delete mState.config;
198         mState.config = overrideConfig;
199 
200         mColorFormat = gl::Format(mState.config->renderTargetFormat);
201         mDSFormat    = gl::Format(mState.config->depthStencilFormat);
202     }
203 
204     ANGLE_TRY(mImplementation->initialize(display));
205 
206     // Initialized here since impl is nullptr in the constructor.
207     // Must happen after implementation initialize for Android.
208     mSwapBehavior = mImplementation->getSwapBehavior();
209 
210     if (mBuftype == EGL_IOSURFACE_ANGLE)
211     {
212         GLenum internalFormat =
213             static_cast<GLenum>(mState.attributes.get(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE));
214         GLenum type = static_cast<GLenum>(mState.attributes.get(EGL_TEXTURE_TYPE_ANGLE));
215 
216         // GL_RGBA + GL_HALF_FLOAT is not a valid format/type combination in GLES like it is in
217         // desktop GL. Adjust the frontend format to be sized RGBA16F.
218         if (internalFormat == GL_RGBA && type == GL_HALF_FLOAT)
219         {
220             internalFormat = GL_RGBA16F;
221         }
222         mColorFormat = gl::Format(internalFormat, type);
223     }
224     if (mBuftype == EGL_D3D_TEXTURE_ANGLE)
225     {
226         const angle::Format *colorFormat = mImplementation->getD3DTextureColorFormat();
227         ASSERT(colorFormat != nullptr);
228         GLenum internalFormat = colorFormat->fboImplementationInternalFormat;
229         mColorFormat          = gl::Format(internalFormat, colorFormat->componentType);
230         mGLColorspace         = EGL_GL_COLORSPACE_LINEAR;
231         if (mColorFormat.info->colorEncoding == GL_SRGB)
232         {
233             mGLColorspace = EGL_GL_COLORSPACE_SRGB;
234         }
235     }
236 
237     if (mType == EGL_WINDOW_BIT && display->getExtensions().getFrameTimestamps)
238     {
239         mState.supportedCompositorTimings = mImplementation->getSupportedCompositorTimings();
240         mState.supportedTimestamps        = mImplementation->getSupportedTimestamps();
241     }
242 
243     mImplObserverBinding.bind(mImplementation);
244 
245     return NoError();
246 }
247 
makeCurrent(const gl::Context * context)248 Error Surface::makeCurrent(const gl::Context *context)
249 {
250     if (isLocked())
251     {
252         return EglBadAccess();
253     }
254     ANGLE_TRY(mImplementation->makeCurrent(context));
255     mIsCurrentOnAnyContext = true;
256     mRefCount++;
257     return NoError();
258 }
259 
unMakeCurrent(const gl::Context * context)260 Error Surface::unMakeCurrent(const gl::Context *context)
261 {
262     ANGLE_TRY(mImplementation->unMakeCurrent(context));
263     mIsCurrentOnAnyContext = false;
264     return releaseRef(context->getDisplay());
265 }
266 
releaseRef(const Display * display)267 Error Surface::releaseRef(const Display *display)
268 {
269     ASSERT(mRefCount > 0);
270     mRefCount--;
271     if (mRefCount == 0 && mDestroyed)
272     {
273         ASSERT(display);
274         return destroyImpl(display);
275     }
276 
277     return NoError();
278 }
279 
onDestroy(const Display * display)280 Error Surface::onDestroy(const Display *display)
281 {
282     mDestroyed = true;
283     if (mRefCount == 0)
284     {
285         return destroyImpl(display);
286     }
287     return NoError();
288 }
289 
setLabel(EGLLabelKHR label)290 void Surface::setLabel(EGLLabelKHR label)
291 {
292     mState.label = label;
293 }
294 
getLabel() const295 EGLLabelKHR Surface::getLabel() const
296 {
297     return mState.label;
298 }
299 
getType() const300 EGLint Surface::getType() const
301 {
302     return mType;
303 }
304 
swap(const gl::Context * context)305 Error Surface::swap(const gl::Context *context)
306 {
307     ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swap");
308     context->onPreSwap();
309 
310     context->getState().getOverlay()->onSwap();
311 
312     ANGLE_TRY(mImplementation->swap(context));
313     postSwap(context);
314     return NoError();
315 }
316 
swapWithDamage(const gl::Context * context,const EGLint * rects,EGLint n_rects)317 Error Surface::swapWithDamage(const gl::Context *context, const EGLint *rects, EGLint n_rects)
318 {
319     ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swapWithDamage");
320     context->onPreSwap();
321 
322     context->getState().getOverlay()->onSwap();
323 
324     ANGLE_TRY(mImplementation->swapWithDamage(context, rects, n_rects));
325     postSwap(context);
326     return NoError();
327 }
328 
swapWithFrameToken(const gl::Context * context,EGLFrameTokenANGLE frameToken)329 Error Surface::swapWithFrameToken(const gl::Context *context, EGLFrameTokenANGLE frameToken)
330 {
331     ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swapWithFrameToken");
332     context->onPreSwap();
333 
334     context->getState().getOverlay()->onSwap();
335 
336     ANGLE_TRY(mImplementation->swapWithFrameToken(context, frameToken));
337     postSwap(context);
338     return NoError();
339 }
340 
postSubBuffer(const gl::Context * context,EGLint x,EGLint y,EGLint width,EGLint height)341 Error Surface::postSubBuffer(const gl::Context *context,
342                              EGLint x,
343                              EGLint y,
344                              EGLint width,
345                              EGLint height)
346 {
347     if (width == 0 || height == 0)
348     {
349         return egl::NoError();
350     }
351 
352     context->getState().getOverlay()->onSwap();
353 
354     ANGLE_TRY(mImplementation->postSubBuffer(context, x, y, width, height));
355     postSwap(context);
356     return NoError();
357 }
358 
setPresentationTime(EGLnsecsANDROID time)359 Error Surface::setPresentationTime(EGLnsecsANDROID time)
360 {
361     return mImplementation->setPresentationTime(time);
362 }
363 
querySurfacePointerANGLE(EGLint attribute,void ** value)364 Error Surface::querySurfacePointerANGLE(EGLint attribute, void **value)
365 {
366     return mImplementation->querySurfacePointerANGLE(attribute, value);
367 }
368 
isPostSubBufferSupported() const369 EGLint Surface::isPostSubBufferSupported() const
370 {
371     return mPostSubBufferRequested && mImplementation->isPostSubBufferSupported();
372 }
373 
setSwapInterval(EGLint interval)374 void Surface::setSwapInterval(EGLint interval)
375 {
376     mImplementation->setSwapInterval(interval);
377 }
378 
setMipmapLevel(EGLint level)379 void Surface::setMipmapLevel(EGLint level)
380 {
381     // Level is set but ignored
382     UNIMPLEMENTED();
383     mMipmapLevel = level;
384 }
385 
setMultisampleResolve(EGLenum resolve)386 void Surface::setMultisampleResolve(EGLenum resolve)
387 {
388     // Behaviour is set but ignored
389     UNIMPLEMENTED();
390     mMultisampleResolve = resolve;
391 }
392 
setSwapBehavior(EGLenum behavior)393 void Surface::setSwapBehavior(EGLenum behavior)
394 {
395     // Behaviour is set but ignored
396     UNIMPLEMENTED();
397     mSwapBehavior = behavior;
398 }
399 
setFixedWidth(EGLint width)400 void Surface::setFixedWidth(EGLint width)
401 {
402     mFixedWidth = width;
403     mImplementation->setFixedWidth(width);
404 }
405 
setFixedHeight(EGLint height)406 void Surface::setFixedHeight(EGLint height)
407 {
408     mFixedHeight = height;
409     mImplementation->setFixedHeight(height);
410 }
411 
getConfig() const412 const Config *Surface::getConfig() const
413 {
414     return mState.config;
415 }
416 
getPixelAspectRatio() const417 EGLint Surface::getPixelAspectRatio() const
418 {
419     return mPixelAspectRatio;
420 }
421 
getRenderBuffer() const422 EGLenum Surface::getRenderBuffer() const
423 {
424     return mRenderBuffer;
425 }
426 
getSwapBehavior() const427 EGLenum Surface::getSwapBehavior() const
428 {
429     return mSwapBehavior;
430 }
431 
getTextureFormat() const432 TextureFormat Surface::getTextureFormat() const
433 {
434     return mTextureFormat;
435 }
436 
getTextureTarget() const437 EGLenum Surface::getTextureTarget() const
438 {
439     return mTextureTarget;
440 }
441 
getLargestPbuffer() const442 bool Surface::getLargestPbuffer() const
443 {
444     return mLargestPbuffer;
445 }
446 
getGLColorspace() const447 EGLenum Surface::getGLColorspace() const
448 {
449     return mGLColorspace;
450 }
451 
getVGAlphaFormat() const452 EGLenum Surface::getVGAlphaFormat() const
453 {
454     return mVGAlphaFormat;
455 }
456 
getVGColorspace() const457 EGLenum Surface::getVGColorspace() const
458 {
459     return mVGColorspace;
460 }
461 
getMipmapTexture() const462 bool Surface::getMipmapTexture() const
463 {
464     return mMipmapTexture;
465 }
466 
getMipmapLevel() const467 EGLint Surface::getMipmapLevel() const
468 {
469     return mMipmapLevel;
470 }
471 
getHorizontalResolution() const472 EGLint Surface::getHorizontalResolution() const
473 {
474     return mHorizontalResolution;
475 }
476 
getVerticalResolution() const477 EGLint Surface::getVerticalResolution() const
478 {
479     return mVerticalResolution;
480 }
481 
getMultisampleResolve() const482 EGLenum Surface::getMultisampleResolve() const
483 {
484     return mMultisampleResolve;
485 }
486 
isFixedSize() const487 EGLint Surface::isFixedSize() const
488 {
489     return mFixedSize;
490 }
491 
getWidth() const492 EGLint Surface::getWidth() const
493 {
494     return mFixedSize ? static_cast<EGLint>(mFixedWidth) : mImplementation->getWidth();
495 }
496 
getHeight() const497 EGLint Surface::getHeight() const
498 {
499     return mFixedSize ? static_cast<EGLint>(mFixedHeight) : mImplementation->getHeight();
500 }
501 
getUserWidth(const egl::Display * display,EGLint * value) const502 egl::Error Surface::getUserWidth(const egl::Display *display, EGLint *value) const
503 {
504     if (mFixedSize)
505     {
506         *value = static_cast<EGLint>(mFixedWidth);
507         return NoError();
508     }
509     else
510     {
511         return mImplementation->getUserWidth(display, value);
512     }
513 }
514 
getUserHeight(const egl::Display * display,EGLint * value) const515 egl::Error Surface::getUserHeight(const egl::Display *display, EGLint *value) const
516 {
517     if (mFixedSize)
518     {
519         *value = static_cast<EGLint>(mFixedHeight);
520         return NoError();
521     }
522     else
523     {
524         return mImplementation->getUserHeight(display, value);
525     }
526 }
527 
bindTexImage(gl::Context * context,gl::Texture * texture,EGLint buffer)528 Error Surface::bindTexImage(gl::Context *context, gl::Texture *texture, EGLint buffer)
529 {
530     ASSERT(!mTexture);
531     ANGLE_TRY(mImplementation->bindTexImage(context, texture, buffer));
532 
533     if (texture->bindTexImageFromSurface(context, this) == angle::Result::Stop)
534     {
535         return Error(EGL_BAD_SURFACE);
536     }
537     mTexture = texture;
538     mRefCount++;
539 
540     return NoError();
541 }
542 
releaseTexImage(const gl::Context * context,EGLint buffer)543 Error Surface::releaseTexImage(const gl::Context *context, EGLint buffer)
544 {
545     ASSERT(context);
546 
547     ANGLE_TRY(mImplementation->releaseTexImage(context, buffer));
548 
549     ASSERT(mTexture);
550     ANGLE_TRY(ResultToEGL(mTexture->releaseTexImageFromSurface(context)));
551 
552     return releaseTexImageFromTexture(context);
553 }
554 
getSyncValues(EGLuint64KHR * ust,EGLuint64KHR * msc,EGLuint64KHR * sbc)555 Error Surface::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc)
556 {
557     return mImplementation->getSyncValues(ust, msc, sbc);
558 }
559 
getMscRate(EGLint * numerator,EGLint * denominator)560 Error Surface::getMscRate(EGLint *numerator, EGLint *denominator)
561 {
562     return mImplementation->getMscRate(numerator, denominator);
563 }
564 
releaseTexImageFromTexture(const gl::Context * context)565 Error Surface::releaseTexImageFromTexture(const gl::Context *context)
566 {
567     ASSERT(mTexture);
568     mTexture = nullptr;
569     return releaseRef(context->getDisplay());
570 }
571 
getAttachmentSize(const gl::ImageIndex &) const572 gl::Extents Surface::getAttachmentSize(const gl::ImageIndex & /*target*/) const
573 {
574     return gl::Extents(getWidth(), getHeight(), 1);
575 }
576 
getAttachmentFormat(GLenum binding,const gl::ImageIndex & target) const577 gl::Format Surface::getAttachmentFormat(GLenum binding, const gl::ImageIndex &target) const
578 {
579     return (binding == GL_BACK ? mColorFormat : mDSFormat);
580 }
581 
getAttachmentSamples(const gl::ImageIndex & target) const582 GLsizei Surface::getAttachmentSamples(const gl::ImageIndex &target) const
583 {
584     return getConfig()->samples;
585 }
586 
isRenderable(const gl::Context * context,GLenum binding,const gl::ImageIndex & imageIndex) const587 bool Surface::isRenderable(const gl::Context *context,
588                            GLenum binding,
589                            const gl::ImageIndex &imageIndex) const
590 {
591     return true;
592 }
593 
isYUV() const594 bool Surface::isYUV() const
595 {
596     // EGL_EXT_yuv_surface is not implemented.
597     return false;
598 }
599 
getId() const600 GLuint Surface::getId() const
601 {
602     UNREACHABLE();
603     return 0;
604 }
605 
getBufferAge(const gl::Context * context,EGLint * age) const606 Error Surface::getBufferAge(const gl::Context *context, EGLint *age) const
607 {
608     // When EGL_BUFFER_PRESERVED, the previous frame contents are copied to
609     // current frame, so the buffer age is always 1.
610     if (mSwapBehavior == EGL_BUFFER_PRESERVED)
611     {
612         if (age != nullptr)
613         {
614             *age = 1;
615         }
616         return egl::NoError();
617     }
618     return mImplementation->getBufferAge(context, age);
619 }
620 
createDefaultFramebuffer(const gl::Context * context,egl::Surface * readSurface)621 gl::Framebuffer *Surface::createDefaultFramebuffer(const gl::Context *context,
622                                                    egl::Surface *readSurface)
623 {
624     return new gl::Framebuffer(context, this, readSurface);
625 }
626 
initState(const gl::ImageIndex &) const627 gl::InitState Surface::initState(const gl::ImageIndex & /*imageIndex*/) const
628 {
629     return mInitState;
630 }
631 
setInitState(const gl::ImageIndex &,gl::InitState initState)632 void Surface::setInitState(const gl::ImageIndex & /*imageIndex*/, gl::InitState initState)
633 {
634     mInitState = initState;
635 }
636 
setTimestampsEnabled(bool enabled)637 void Surface::setTimestampsEnabled(bool enabled)
638 {
639     mImplementation->setTimestampsEnabled(enabled);
640     mState.timestampsEnabled = enabled;
641 }
642 
isTimestampsEnabled() const643 bool Surface::isTimestampsEnabled() const
644 {
645     return mState.timestampsEnabled;
646 }
647 
hasProtectedContent() const648 bool Surface::hasProtectedContent() const
649 {
650     return mState.hasProtectedContent();
651 }
652 
getSupportedCompositorTimings() const653 const SupportedCompositorTiming &Surface::getSupportedCompositorTimings() const
654 {
655     return mState.supportedCompositorTimings;
656 }
657 
getCompositorTiming(EGLint numTimestamps,const EGLint * names,EGLnsecsANDROID * values) const658 Error Surface::getCompositorTiming(EGLint numTimestamps,
659                                    const EGLint *names,
660                                    EGLnsecsANDROID *values) const
661 {
662     return mImplementation->getCompositorTiming(numTimestamps, names, values);
663 }
664 
getNextFrameId(EGLuint64KHR * frameId) const665 Error Surface::getNextFrameId(EGLuint64KHR *frameId) const
666 {
667     return mImplementation->getNextFrameId(frameId);
668 }
669 
getSupportedTimestamps() const670 const SupportedTimestamps &Surface::getSupportedTimestamps() const
671 {
672     return mState.supportedTimestamps;
673 }
674 
getFrameTimestamps(EGLuint64KHR frameId,EGLint numTimestamps,const EGLint * timestamps,EGLnsecsANDROID * values) const675 Error Surface::getFrameTimestamps(EGLuint64KHR frameId,
676                                   EGLint numTimestamps,
677                                   const EGLint *timestamps,
678                                   EGLnsecsANDROID *values) const
679 {
680     return mImplementation->getFrameTimestamps(frameId, numTimestamps, timestamps, values);
681 }
682 
onSubjectStateChange(angle::SubjectIndex index,angle::SubjectMessage message)683 void Surface::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
684 {
685     ASSERT(index == kSurfaceImplSubjectIndex);
686     switch (message)
687     {
688         case angle::SubjectMessage::SubjectChanged:
689             onStateChange(angle::SubjectMessage::ContentsChanged);
690             break;
691         case angle::SubjectMessage::SurfaceChanged:
692             onStateChange(angle::SubjectMessage::SurfaceChanged);
693             break;
694         default:
695             UNREACHABLE();
696             break;
697     }
698 }
699 
setRenderBuffer(EGLint renderBuffer)700 Error Surface::setRenderBuffer(EGLint renderBuffer)
701 {
702     ANGLE_TRY(mImplementation->setRenderBuffer(renderBuffer));
703     mRenderBuffer = renderBuffer;
704     return NoError();
705 }
706 
isLocked() const707 bool Surface::isLocked() const
708 {
709     return (mLockBufferPtr != nullptr);
710 }
711 
getBitmapPitch() const712 EGLint Surface::getBitmapPitch() const
713 {
714     return mLockBufferPitch;
715 }
716 
getBitmapOrigin() const717 EGLint Surface::getBitmapOrigin() const
718 {
719     return mImplementation->origin();
720 }
721 
getRedOffset() const722 EGLint Surface::getRedOffset() const
723 {
724     const gl::InternalFormat &format = *mColorFormat.info;
725     if (gl::IsBGRAFormat(format.internalFormat))
726     {
727         return format.blueBits + format.greenBits;
728     }
729     else
730     {
731         return 0;
732     }
733 }
734 
getGreenOffset() const735 EGLint Surface::getGreenOffset() const
736 {
737     const gl::InternalFormat &format = *mColorFormat.info;
738     if (gl::IsBGRAFormat(format.internalFormat))
739     {
740         return format.blueBits;
741     }
742     else
743     {
744         return format.redBits;
745     }
746 }
747 
getBlueOffset() const748 EGLint Surface::getBlueOffset() const
749 {
750     const gl::InternalFormat &format = *mColorFormat.info;
751     if (gl::IsBGRAFormat(format.internalFormat))
752     {
753         return 0;
754     }
755     else
756     {
757         return format.redBits + format.greenBits;
758     }
759 }
760 
getAlphaOffset() const761 EGLint Surface::getAlphaOffset() const
762 {
763     const gl::InternalFormat &format = *mColorFormat.info;
764     if (format.isLUMA())
765     {
766         return format.luminanceBits;  // Luma always first, alpha optional
767     }
768     // For RGBA/BGRA alpha is last
769     return format.blueBits + format.greenBits + format.redBits;
770 }
771 
getLuminanceOffset() const772 EGLint Surface::getLuminanceOffset() const
773 {
774     return 0;
775 }
776 
getBitmapPixelSize() const777 EGLint Surface::getBitmapPixelSize() const
778 {
779     constexpr EGLint kBitsPerByte    = 8;
780     const gl::InternalFormat &format = *mColorFormat.info;
781     return (format.pixelBytes * kBitsPerByte);
782 }
783 
getBitmapPointer() const784 EGLAttribKHR Surface::getBitmapPointer() const
785 {
786     return static_cast<EGLAttribKHR>((intptr_t)mLockBufferPtr);
787 }
788 
lockSurfaceKHR(const egl::Display * display,const AttributeMap & attributes)789 egl::Error Surface::lockSurfaceKHR(const egl::Display *display, const AttributeMap &attributes)
790 {
791     EGLint lockBufferUsageHint = attributes.getAsInt(
792         EGL_LOCK_USAGE_HINT_KHR, (EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR));
793 
794     bool preservePixels = ((attributes.getAsInt(EGL_MAP_PRESERVE_PIXELS_KHR, false) == EGL_TRUE) ||
795                            (mSwapBehavior == EGL_BUFFER_PRESERVED));
796 
797     return mImplementation->lockSurface(display, lockBufferUsageHint, preservePixels,
798                                         &mLockBufferPtr, &mLockBufferPitch);
799 }
800 
unlockSurfaceKHR(const egl::Display * display)801 egl::Error Surface::unlockSurfaceKHR(const egl::Display *display)
802 {
803     mLockBufferPtr   = nullptr;
804     mLockBufferPitch = 0;
805     return mImplementation->unlockSurface(display, true);
806 }
807 
WindowSurface(rx::EGLImplFactory * implFactory,const egl::Config * config,EGLNativeWindowType window,const AttributeMap & attribs,bool robustResourceInit)808 WindowSurface::WindowSurface(rx::EGLImplFactory *implFactory,
809                              const egl::Config *config,
810                              EGLNativeWindowType window,
811                              const AttributeMap &attribs,
812                              bool robustResourceInit)
813     : Surface(EGL_WINDOW_BIT, config, attribs, robustResourceInit)
814 {
815     mImplementation = implFactory->createWindowSurface(mState, window, attribs);
816 }
817 
~WindowSurface()818 WindowSurface::~WindowSurface() {}
819 
PbufferSurface(rx::EGLImplFactory * implFactory,const Config * config,const AttributeMap & attribs,bool robustResourceInit)820 PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory,
821                                const Config *config,
822                                const AttributeMap &attribs,
823                                bool robustResourceInit)
824     : Surface(EGL_PBUFFER_BIT, config, attribs, robustResourceInit)
825 {
826     mImplementation = implFactory->createPbufferSurface(mState, attribs);
827 }
828 
PbufferSurface(rx::EGLImplFactory * implFactory,const Config * config,EGLenum buftype,EGLClientBuffer clientBuffer,const AttributeMap & attribs,bool robustResourceInit)829 PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory,
830                                const Config *config,
831                                EGLenum buftype,
832                                EGLClientBuffer clientBuffer,
833                                const AttributeMap &attribs,
834                                bool robustResourceInit)
835     : Surface(EGL_PBUFFER_BIT, config, attribs, robustResourceInit, buftype)
836 {
837     mImplementation =
838         implFactory->createPbufferFromClientBuffer(mState, buftype, clientBuffer, attribs);
839 }
840 
~PbufferSurface()841 PbufferSurface::~PbufferSurface() {}
842 
PixmapSurface(rx::EGLImplFactory * implFactory,const Config * config,NativePixmapType nativePixmap,const AttributeMap & attribs,bool robustResourceInit)843 PixmapSurface::PixmapSurface(rx::EGLImplFactory *implFactory,
844                              const Config *config,
845                              NativePixmapType nativePixmap,
846                              const AttributeMap &attribs,
847                              bool robustResourceInit)
848     : Surface(EGL_PIXMAP_BIT, config, attribs, robustResourceInit)
849 {
850     mImplementation = implFactory->createPixmapSurface(mState, nativePixmap, attribs);
851 }
852 
~PixmapSurface()853 PixmapSurface::~PixmapSurface() {}
854 
855 // SurfaceDeleter implementation.
856 
SurfaceDeleter(const Display * display)857 SurfaceDeleter::SurfaceDeleter(const Display *display) : mDisplay(display) {}
858 
~SurfaceDeleter()859 SurfaceDeleter::~SurfaceDeleter() {}
860 
operator ()(Surface * surface)861 void SurfaceDeleter::operator()(Surface *surface)
862 {
863     ANGLE_SWALLOW_ERR(surface->onDestroy(mDisplay));
864 }
865 
866 }  // namespace egl
867