• 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/Thread.h"
21 #include "libANGLE/formatutils.h"
22 #include "libANGLE/renderer/EGLImplFactory.h"
23 #include "libANGLE/trace.h"
24 
25 namespace egl
26 {
27 
SurfaceState(const egl::Config * configIn,const AttributeMap & attributesIn)28 SurfaceState::SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn)
29     : label(nullptr), config(configIn), attributes(attributesIn), timestampsEnabled(false)
30 {}
31 
32 SurfaceState::~SurfaceState() = default;
33 
Surface(EGLint surfaceType,const egl::Config * config,const AttributeMap & attributes,EGLenum buftype)34 Surface::Surface(EGLint surfaceType,
35                  const egl::Config *config,
36                  const AttributeMap &attributes,
37                  EGLenum buftype)
38     : FramebufferAttachmentObject(),
39       mState(config, attributes),
40       mImplementation(nullptr),
41       mRefCount(0),
42       mDestroyed(false),
43       mType(surfaceType),
44       mBuftype(buftype),
45       mPostSubBufferRequested(false),
46       mLargestPbuffer(false),
47       mGLColorspace(EGL_GL_COLORSPACE_LINEAR),
48       mVGAlphaFormat(EGL_VG_ALPHA_FORMAT_NONPRE),
49       mVGColorspace(EGL_VG_COLORSPACE_sRGB),
50       mMipmapTexture(false),
51       mMipmapLevel(0),
52       mHorizontalResolution(EGL_UNKNOWN),
53       mVerticalResolution(EGL_UNKNOWN),
54       mMultisampleResolve(EGL_MULTISAMPLE_RESOLVE_DEFAULT),
55       mFixedSize(false),
56       mFixedWidth(0),
57       mFixedHeight(0),
58       mTextureFormat(TextureFormat::NoTexture),
59       mTextureTarget(EGL_NO_TEXTURE),
60       // FIXME: Determine actual pixel aspect ratio
61       mPixelAspectRatio(static_cast<EGLint>(1.0 * EGL_DISPLAY_SCALING)),
62       mRenderBuffer(EGL_BACK_BUFFER),
63       mSwapBehavior(EGL_NONE),
64       mOrientation(0),
65       mTexture(nullptr),
66       mColorFormat(config->renderTargetFormat),
67       mDSFormat(config->depthStencilFormat),
68       mInitState(gl::InitState::Initialized)
69 {
70     mPostSubBufferRequested =
71         (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE);
72     mFlexibleSurfaceCompatibilityRequested =
73         (attributes.get(EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, EGL_FALSE) == EGL_TRUE);
74 
75     if (mType == EGL_PBUFFER_BIT)
76     {
77         mLargestPbuffer = (attributes.get(EGL_LARGEST_PBUFFER, EGL_FALSE) == EGL_TRUE);
78     }
79 
80     mGLColorspace =
81         static_cast<EGLenum>(attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR));
82     mVGAlphaFormat =
83         static_cast<EGLenum>(attributes.get(EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_NONPRE));
84     mVGColorspace = static_cast<EGLenum>(attributes.get(EGL_VG_COLORSPACE, EGL_VG_COLORSPACE_sRGB));
85     mMipmapTexture = (attributes.get(EGL_MIPMAP_TEXTURE, EGL_FALSE) == EGL_TRUE);
86 
87     mDirectComposition = (attributes.get(EGL_DIRECT_COMPOSITION_ANGLE, EGL_FALSE) == EGL_TRUE);
88 
89     mRobustResourceInitialization =
90         (attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
91     if (mRobustResourceInitialization)
92     {
93         mInitState = gl::InitState::MayNeedInit;
94     }
95 
96     mFixedSize = (attributes.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE);
97     if (mFixedSize)
98     {
99         mFixedWidth  = static_cast<size_t>(attributes.get(EGL_WIDTH, 0));
100         mFixedHeight = static_cast<size_t>(attributes.get(EGL_HEIGHT, 0));
101     }
102 
103     if (mType != EGL_WINDOW_BIT)
104     {
105         mTextureFormat = attributes.getAsPackedEnum(EGL_TEXTURE_FORMAT, TextureFormat::NoTexture);
106         mTextureTarget = static_cast<EGLenum>(attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE));
107     }
108 
109     mOrientation = static_cast<EGLint>(attributes.get(EGL_SURFACE_ORIENTATION_ANGLE, 0));
110 }
111 
~Surface()112 Surface::~Surface() {}
113 
getAttachmentImpl() const114 rx::FramebufferAttachmentObjectImpl *Surface::getAttachmentImpl() const
115 {
116     return mImplementation;
117 }
118 
destroyImpl(const Display * display)119 Error Surface::destroyImpl(const Display *display)
120 {
121     if (mImplementation)
122     {
123         mImplementation->destroy(display);
124     }
125 
126     ASSERT(!mTexture);
127 
128     SafeDelete(mImplementation);
129 
130     delete this;
131     return NoError();
132 }
133 
postSwap(const gl::Context * context)134 void Surface::postSwap(const gl::Context *context)
135 {
136     if (mRobustResourceInitialization && mSwapBehavior != EGL_BUFFER_PRESERVED)
137     {
138         mInitState = gl::InitState::MayNeedInit;
139         onStateChange(angle::SubjectMessage::SubjectChanged);
140     }
141 
142     context->onPostSwap();
143 }
144 
initialize(const Display * display)145 Error Surface::initialize(const Display *display)
146 {
147     ANGLE_TRY(mImplementation->initialize(display));
148 
149     // Initialized here since impl is nullptr in the constructor.
150     // Must happen after implementation initialize for Android.
151     mSwapBehavior = mImplementation->getSwapBehavior();
152 
153     if (mBuftype == EGL_IOSURFACE_ANGLE)
154     {
155         GLenum internalFormat =
156             static_cast<GLenum>(mState.attributes.get(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE));
157         GLenum type  = static_cast<GLenum>(mState.attributes.get(EGL_TEXTURE_TYPE_ANGLE));
158         mColorFormat = gl::Format(internalFormat, type);
159     }
160     if (mBuftype == EGL_D3D_TEXTURE_ANGLE)
161     {
162         const angle::Format *colorFormat = mImplementation->getD3DTextureColorFormat();
163         ASSERT(colorFormat != nullptr);
164         GLenum internalFormat = colorFormat->fboImplementationInternalFormat;
165         mColorFormat          = gl::Format(internalFormat, colorFormat->componentType);
166         mGLColorspace         = EGL_GL_COLORSPACE_LINEAR;
167         if (mColorFormat.info->colorEncoding == GL_SRGB)
168         {
169             mGLColorspace = EGL_GL_COLORSPACE_SRGB;
170         }
171     }
172 
173     if (mType == EGL_WINDOW_BIT && display->getExtensions().getFrameTimestamps)
174     {
175         mState.supportedCompositorTimings = mImplementation->getSupportedCompositorTimings();
176         mState.supportedTimestamps        = mImplementation->getSupportedTimestamps();
177     }
178 
179     return NoError();
180 }
181 
makeCurrent(const gl::Context * context)182 Error Surface::makeCurrent(const gl::Context *context)
183 {
184     ANGLE_TRY(mImplementation->makeCurrent(context));
185 
186     mRefCount++;
187     return NoError();
188 }
189 
unMakeCurrent(const gl::Context * context)190 Error Surface::unMakeCurrent(const gl::Context *context)
191 {
192     ANGLE_TRY(mImplementation->unMakeCurrent(context));
193     return releaseRef(context->getDisplay());
194 }
195 
releaseRef(const Display * display)196 Error Surface::releaseRef(const Display *display)
197 {
198     ASSERT(mRefCount > 0);
199     mRefCount--;
200     if (mRefCount == 0 && mDestroyed)
201     {
202         ASSERT(display);
203         return destroyImpl(display);
204     }
205 
206     return NoError();
207 }
208 
onDestroy(const Display * display)209 Error Surface::onDestroy(const Display *display)
210 {
211     mDestroyed = true;
212     if (mRefCount == 0)
213     {
214         return destroyImpl(display);
215     }
216     return NoError();
217 }
218 
setLabel(EGLLabelKHR label)219 void Surface::setLabel(EGLLabelKHR label)
220 {
221     mState.label = label;
222 }
223 
getLabel() const224 EGLLabelKHR Surface::getLabel() const
225 {
226     return mState.label;
227 }
228 
getType() const229 EGLint Surface::getType() const
230 {
231     return mType;
232 }
233 
swap(const gl::Context * context)234 Error Surface::swap(const gl::Context *context)
235 {
236     ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swap");
237 
238     ANGLE_TRY(mImplementation->swap(context));
239     postSwap(context);
240     return NoError();
241 }
242 
swapWithDamage(const gl::Context * context,EGLint * rects,EGLint n_rects)243 Error Surface::swapWithDamage(const gl::Context *context, EGLint *rects, EGLint n_rects)
244 {
245     ANGLE_TRY(mImplementation->swapWithDamage(context, rects, n_rects));
246     postSwap(context);
247     return NoError();
248 }
249 
postSubBuffer(const gl::Context * context,EGLint x,EGLint y,EGLint width,EGLint height)250 Error Surface::postSubBuffer(const gl::Context *context,
251                              EGLint x,
252                              EGLint y,
253                              EGLint width,
254                              EGLint height)
255 {
256     if (width == 0 || height == 0)
257     {
258         return egl::NoError();
259     }
260 
261     ANGLE_TRY(mImplementation->postSubBuffer(context, x, y, width, height));
262     postSwap(context);
263     return NoError();
264 }
265 
setPresentationTime(EGLnsecsANDROID time)266 Error Surface::setPresentationTime(EGLnsecsANDROID time)
267 {
268     return mImplementation->setPresentationTime(time);
269 }
270 
querySurfacePointerANGLE(EGLint attribute,void ** value)271 Error Surface::querySurfacePointerANGLE(EGLint attribute, void **value)
272 {
273     return mImplementation->querySurfacePointerANGLE(attribute, value);
274 }
275 
isPostSubBufferSupported() const276 EGLint Surface::isPostSubBufferSupported() const
277 {
278     return mPostSubBufferRequested && mImplementation->isPostSubBufferSupported();
279 }
280 
setSwapInterval(EGLint interval)281 void Surface::setSwapInterval(EGLint interval)
282 {
283     mImplementation->setSwapInterval(interval);
284 }
285 
setMipmapLevel(EGLint level)286 void Surface::setMipmapLevel(EGLint level)
287 {
288     // Level is set but ignored
289     UNIMPLEMENTED();
290     mMipmapLevel = level;
291 }
292 
setMultisampleResolve(EGLenum resolve)293 void Surface::setMultisampleResolve(EGLenum resolve)
294 {
295     // Behaviour is set but ignored
296     UNIMPLEMENTED();
297     mMultisampleResolve = resolve;
298 }
299 
setSwapBehavior(EGLenum behavior)300 void Surface::setSwapBehavior(EGLenum behavior)
301 {
302     // Behaviour is set but ignored
303     UNIMPLEMENTED();
304     mSwapBehavior = behavior;
305 }
306 
setFixedWidth(EGLint width)307 void Surface::setFixedWidth(EGLint width)
308 {
309     mFixedWidth = width;
310     mImplementation->setFixedWidth(width);
311 }
312 
setFixedHeight(EGLint height)313 void Surface::setFixedHeight(EGLint height)
314 {
315     mFixedHeight = height;
316     mImplementation->setFixedHeight(height);
317 }
318 
getConfig() const319 const Config *Surface::getConfig() const
320 {
321     return mState.config;
322 }
323 
getPixelAspectRatio() const324 EGLint Surface::getPixelAspectRatio() const
325 {
326     return mPixelAspectRatio;
327 }
328 
getRenderBuffer() const329 EGLenum Surface::getRenderBuffer() const
330 {
331     return mRenderBuffer;
332 }
333 
getSwapBehavior() const334 EGLenum Surface::getSwapBehavior() const
335 {
336     return mSwapBehavior;
337 }
338 
getTextureFormat() const339 TextureFormat Surface::getTextureFormat() const
340 {
341     return mTextureFormat;
342 }
343 
getTextureTarget() const344 EGLenum Surface::getTextureTarget() const
345 {
346     return mTextureTarget;
347 }
348 
getLargestPbuffer() const349 bool Surface::getLargestPbuffer() const
350 {
351     return mLargestPbuffer;
352 }
353 
getGLColorspace() const354 EGLenum Surface::getGLColorspace() const
355 {
356     return mGLColorspace;
357 }
358 
getVGAlphaFormat() const359 EGLenum Surface::getVGAlphaFormat() const
360 {
361     return mVGAlphaFormat;
362 }
363 
getVGColorspace() const364 EGLenum Surface::getVGColorspace() const
365 {
366     return mVGColorspace;
367 }
368 
getMipmapTexture() const369 bool Surface::getMipmapTexture() const
370 {
371     return mMipmapTexture;
372 }
373 
getMipmapLevel() const374 EGLint Surface::getMipmapLevel() const
375 {
376     return mMipmapLevel;
377 }
378 
getHorizontalResolution() const379 EGLint Surface::getHorizontalResolution() const
380 {
381     return mHorizontalResolution;
382 }
383 
getVerticalResolution() const384 EGLint Surface::getVerticalResolution() const
385 {
386     return mVerticalResolution;
387 }
388 
getMultisampleResolve() const389 EGLenum Surface::getMultisampleResolve() const
390 {
391     return mMultisampleResolve;
392 }
393 
isFixedSize() const394 EGLint Surface::isFixedSize() const
395 {
396     return mFixedSize;
397 }
398 
getWidth() const399 EGLint Surface::getWidth() const
400 {
401     return mFixedSize ? static_cast<EGLint>(mFixedWidth) : mImplementation->getWidth();
402 }
403 
getHeight() const404 EGLint Surface::getHeight() const
405 {
406     return mFixedSize ? static_cast<EGLint>(mFixedHeight) : mImplementation->getHeight();
407 }
408 
bindTexImage(gl::Context * context,gl::Texture * texture,EGLint buffer)409 Error Surface::bindTexImage(gl::Context *context, gl::Texture *texture, EGLint buffer)
410 {
411     ASSERT(!mTexture);
412     ANGLE_TRY(mImplementation->bindTexImage(context, texture, buffer));
413 
414     if (texture->bindTexImageFromSurface(context, this) == angle::Result::Stop)
415     {
416         return Error(EGL_BAD_SURFACE);
417     }
418     mTexture = texture;
419     mRefCount++;
420 
421     return NoError();
422 }
423 
releaseTexImage(const gl::Context * context,EGLint buffer)424 Error Surface::releaseTexImage(const gl::Context *context, EGLint buffer)
425 {
426     ASSERT(context);
427 
428     ANGLE_TRY(mImplementation->releaseTexImage(context, buffer));
429 
430     ASSERT(mTexture);
431     ANGLE_TRY(ResultToEGL(mTexture->releaseTexImageFromSurface(context)));
432 
433     return releaseTexImageFromTexture(context);
434 }
435 
getSyncValues(EGLuint64KHR * ust,EGLuint64KHR * msc,EGLuint64KHR * sbc)436 Error Surface::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc)
437 {
438     return mImplementation->getSyncValues(ust, msc, sbc);
439 }
440 
releaseTexImageFromTexture(const gl::Context * context)441 Error Surface::releaseTexImageFromTexture(const gl::Context *context)
442 {
443     ASSERT(mTexture);
444     mTexture = nullptr;
445     return releaseRef(context->getDisplay());
446 }
447 
getAttachmentSize(const gl::ImageIndex &) const448 gl::Extents Surface::getAttachmentSize(const gl::ImageIndex & /*target*/) const
449 {
450     return gl::Extents(getWidth(), getHeight(), 1);
451 }
452 
getAttachmentFormat(GLenum binding,const gl::ImageIndex & target) const453 gl::Format Surface::getAttachmentFormat(GLenum binding, const gl::ImageIndex &target) const
454 {
455     return (binding == GL_BACK ? mColorFormat : mDSFormat);
456 }
457 
getAttachmentSamples(const gl::ImageIndex & target) const458 GLsizei Surface::getAttachmentSamples(const gl::ImageIndex &target) const
459 {
460     return getConfig()->samples;
461 }
462 
isRenderable(const gl::Context * context,GLenum binding,const gl::ImageIndex & imageIndex) const463 bool Surface::isRenderable(const gl::Context *context,
464                            GLenum binding,
465                            const gl::ImageIndex &imageIndex) const
466 {
467     return true;
468 }
469 
getId() const470 GLuint Surface::getId() const
471 {
472     UNREACHABLE();
473     return 0;
474 }
475 
createDefaultFramebuffer(const gl::Context * context)476 gl::Framebuffer *Surface::createDefaultFramebuffer(const gl::Context *context)
477 {
478     return new gl::Framebuffer(context, this);
479 }
480 
initState(const gl::ImageIndex &) const481 gl::InitState Surface::initState(const gl::ImageIndex & /*imageIndex*/) const
482 {
483     return mInitState;
484 }
485 
setInitState(const gl::ImageIndex &,gl::InitState initState)486 void Surface::setInitState(const gl::ImageIndex & /*imageIndex*/, gl::InitState initState)
487 {
488     mInitState = initState;
489 }
490 
setTimestampsEnabled(bool enabled)491 void Surface::setTimestampsEnabled(bool enabled)
492 {
493     mImplementation->setTimestampsEnabled(enabled);
494     mState.timestampsEnabled = enabled;
495 }
496 
isTimestampsEnabled() const497 bool Surface::isTimestampsEnabled() const
498 {
499     return mState.timestampsEnabled;
500 }
501 
getSupportedCompositorTimings() const502 const SupportedCompositorTiming &Surface::getSupportedCompositorTimings() const
503 {
504     return mState.supportedCompositorTimings;
505 }
506 
getCompositorTiming(EGLint numTimestamps,const EGLint * names,EGLnsecsANDROID * values) const507 Error Surface::getCompositorTiming(EGLint numTimestamps,
508                                    const EGLint *names,
509                                    EGLnsecsANDROID *values) const
510 {
511     return mImplementation->getCompositorTiming(numTimestamps, names, values);
512 }
513 
getNextFrameId(EGLuint64KHR * frameId) const514 Error Surface::getNextFrameId(EGLuint64KHR *frameId) const
515 {
516     return mImplementation->getNextFrameId(frameId);
517 }
518 
getSupportedTimestamps() const519 const SupportedTimestamps &Surface::getSupportedTimestamps() const
520 {
521     return mState.supportedTimestamps;
522 }
523 
getFrameTimestamps(EGLuint64KHR frameId,EGLint numTimestamps,const EGLint * timestamps,EGLnsecsANDROID * values) const524 Error Surface::getFrameTimestamps(EGLuint64KHR frameId,
525                                   EGLint numTimestamps,
526                                   const EGLint *timestamps,
527                                   EGLnsecsANDROID *values) const
528 {
529     return mImplementation->getFrameTimestamps(frameId, numTimestamps, timestamps, values);
530 }
531 
WindowSurface(rx::EGLImplFactory * implFactory,const egl::Config * config,EGLNativeWindowType window,const AttributeMap & attribs)532 WindowSurface::WindowSurface(rx::EGLImplFactory *implFactory,
533                              const egl::Config *config,
534                              EGLNativeWindowType window,
535                              const AttributeMap &attribs)
536     : Surface(EGL_WINDOW_BIT, config, attribs)
537 {
538     mImplementation = implFactory->createWindowSurface(mState, window, attribs);
539 }
540 
~WindowSurface()541 WindowSurface::~WindowSurface() {}
542 
PbufferSurface(rx::EGLImplFactory * implFactory,const Config * config,const AttributeMap & attribs)543 PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory,
544                                const Config *config,
545                                const AttributeMap &attribs)
546     : Surface(EGL_PBUFFER_BIT, config, attribs)
547 {
548     mImplementation = implFactory->createPbufferSurface(mState, attribs);
549 }
550 
PbufferSurface(rx::EGLImplFactory * implFactory,const Config * config,EGLenum buftype,EGLClientBuffer clientBuffer,const AttributeMap & attribs)551 PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory,
552                                const Config *config,
553                                EGLenum buftype,
554                                EGLClientBuffer clientBuffer,
555                                const AttributeMap &attribs)
556     : Surface(EGL_PBUFFER_BIT, config, attribs, buftype)
557 {
558     mImplementation =
559         implFactory->createPbufferFromClientBuffer(mState, buftype, clientBuffer, attribs);
560 }
561 
~PbufferSurface()562 PbufferSurface::~PbufferSurface() {}
563 
PixmapSurface(rx::EGLImplFactory * implFactory,const Config * config,NativePixmapType nativePixmap,const AttributeMap & attribs)564 PixmapSurface::PixmapSurface(rx::EGLImplFactory *implFactory,
565                              const Config *config,
566                              NativePixmapType nativePixmap,
567                              const AttributeMap &attribs)
568     : Surface(EGL_PIXMAP_BIT, config, attribs)
569 {
570     mImplementation = implFactory->createPixmapSurface(mState, nativePixmap, attribs);
571 }
572 
~PixmapSurface()573 PixmapSurface::~PixmapSurface() {}
574 
575 // SurfaceDeleter implementation.
576 
SurfaceDeleter(const Display * display)577 SurfaceDeleter::SurfaceDeleter(const Display *display) : mDisplay(display) {}
578 
~SurfaceDeleter()579 SurfaceDeleter::~SurfaceDeleter() {}
580 
operator ()(Surface * surface)581 void SurfaceDeleter::operator()(Surface *surface)
582 {
583     ANGLE_SWALLOW_ERR(surface->onDestroy(mDisplay));
584 }
585 
586 }  // namespace egl
587