tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Surface.cpp (25477B)


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