tor-browser

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

Renderbuffer.cpp (12985B)


      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 // Renderbuffer.cpp: Implements the renderer-agnostic gl::Renderbuffer class,
      8 // GL renderbuffer objects and related functionality.
      9 // [OpenGL ES 2.0.24] section 4.4.3 page 108.
     10 
     11 #include "libANGLE/Renderbuffer.h"
     12 
     13 #include "common/utilities.h"
     14 #include "libANGLE/Context.h"
     15 #include "libANGLE/FramebufferAttachment.h"
     16 #include "libANGLE/Image.h"
     17 #include "libANGLE/Renderbuffer.h"
     18 #include "libANGLE/Texture.h"
     19 #include "libANGLE/formatutils.h"
     20 #include "libANGLE/renderer/GLImplFactory.h"
     21 #include "libANGLE/renderer/d3d/RenderTargetD3D.h"
     22 
     23 namespace gl
     24 {
     25 namespace
     26 {
     27 angle::SubjectIndex kRenderbufferImplSubjectIndex = 0;
     28 
     29 InitState DetermineInitState(const Context *context)
     30 {
     31    return (context && context->isRobustResourceInitEnabled()) ? InitState::MayNeedInit
     32                                                               : InitState::Initialized;
     33 }
     34 }  // namespace
     35 
     36 // RenderbufferState implementation.
     37 RenderbufferState::RenderbufferState()
     38    : mWidth(0),
     39      mHeight(0),
     40      mFormat(GL_RGBA4),
     41      mSamples(0),
     42      mMultisamplingMode(MultisamplingMode::Regular),
     43      mHasProtectedContent(false),
     44      mInitState(InitState::Initialized)
     45 {}
     46 
     47 RenderbufferState::~RenderbufferState() {}
     48 
     49 GLsizei RenderbufferState::getWidth() const
     50 {
     51    return mWidth;
     52 }
     53 
     54 GLsizei RenderbufferState::getHeight() const
     55 {
     56    return mHeight;
     57 }
     58 
     59 const Format &RenderbufferState::getFormat() const
     60 {
     61    return mFormat;
     62 }
     63 
     64 GLsizei RenderbufferState::getSamples() const
     65 {
     66    return mSamples;
     67 }
     68 
     69 MultisamplingMode RenderbufferState::getMultisamplingMode() const
     70 {
     71    return mMultisamplingMode;
     72 }
     73 
     74 InitState RenderbufferState::getInitState() const
     75 {
     76    return mInitState;
     77 }
     78 
     79 void RenderbufferState::update(GLsizei width,
     80                               GLsizei height,
     81                               const Format &format,
     82                               GLsizei samples,
     83                               MultisamplingMode multisamplingMode,
     84                               InitState initState)
     85 {
     86    mWidth               = width;
     87    mHeight              = height;
     88    mFormat              = format;
     89    mSamples             = samples;
     90    mMultisamplingMode   = multisamplingMode;
     91    mInitState           = initState;
     92    mHasProtectedContent = false;
     93 }
     94 
     95 void RenderbufferState::setProtectedContent(bool hasProtectedContent)
     96 {
     97    mHasProtectedContent = hasProtectedContent;
     98 }
     99 
    100 // Renderbuffer implementation.
    101 Renderbuffer::Renderbuffer(rx::GLImplFactory *implFactory, RenderbufferID id)
    102    : RefCountObject(implFactory->generateSerial(), id),
    103      mState(),
    104      mImplementation(implFactory->createRenderbuffer(mState)),
    105      mLabel(),
    106      mImplObserverBinding(this, kRenderbufferImplSubjectIndex)
    107 {
    108    mImplObserverBinding.bind(mImplementation.get());
    109 }
    110 
    111 void Renderbuffer::onDestroy(const Context *context)
    112 {
    113    egl::RefCountObjectReleaser<egl::Image> releaseImage;
    114    (void)orphanImages(context, &releaseImage);
    115 
    116    if (mImplementation)
    117    {
    118        mImplementation->onDestroy(context);
    119    }
    120 }
    121 
    122 Renderbuffer::~Renderbuffer() {}
    123 
    124 angle::Result Renderbuffer::setLabel(const Context *context, const std::string &label)
    125 {
    126    mLabel = label;
    127 
    128    if (mImplementation)
    129    {
    130        return mImplementation->onLabelUpdate(context);
    131    }
    132    return angle::Result::Continue;
    133 }
    134 
    135 const std::string &Renderbuffer::getLabel() const
    136 {
    137    return mLabel;
    138 }
    139 
    140 angle::Result Renderbuffer::setStorage(const Context *context,
    141                                       GLenum internalformat,
    142                                       GLsizei width,
    143                                       GLsizei height)
    144 {
    145 
    146    egl::RefCountObjectReleaser<egl::Image> releaseImage;
    147    ANGLE_TRY(orphanImages(context, &releaseImage));
    148 
    149    ANGLE_TRY(mImplementation->setStorage(context, internalformat, width, height));
    150 
    151    mState.update(width, height, Format(internalformat), 0, MultisamplingMode::Regular,
    152                  DetermineInitState(context));
    153    onStateChange(angle::SubjectMessage::SubjectChanged);
    154 
    155    return angle::Result::Continue;
    156 }
    157 
    158 angle::Result Renderbuffer::setStorageMultisample(const Context *context,
    159                                                  GLsizei samplesIn,
    160                                                  GLenum internalformat,
    161                                                  GLsizei width,
    162                                                  GLsizei height,
    163                                                  MultisamplingMode mode)
    164 {
    165    egl::RefCountObjectReleaser<egl::Image> releaseImage;
    166    ANGLE_TRY(orphanImages(context, &releaseImage));
    167 
    168    // Potentially adjust "samplesIn" to a supported value
    169    const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
    170    GLsizei samples               = formatCaps.getNearestSamples(samplesIn);
    171 
    172    ANGLE_TRY(mImplementation->setStorageMultisample(context, samples, internalformat, width,
    173                                                     height, mode));
    174 
    175    mState.update(width, height, Format(internalformat), samples, mode,
    176                  DetermineInitState(context));
    177    onStateChange(angle::SubjectMessage::SubjectChanged);
    178 
    179    return angle::Result::Continue;
    180 }
    181 
    182 angle::Result Renderbuffer::setStorageEGLImageTarget(const Context *context, egl::Image *image)
    183 {
    184    egl::RefCountObjectReleaser<egl::Image> releaseImage;
    185    ANGLE_TRY(orphanImages(context, &releaseImage));
    186 
    187    ANGLE_TRY(mImplementation->setStorageEGLImageTarget(context, image));
    188 
    189    setTargetImage(context, image);
    190 
    191    mState.update(static_cast<GLsizei>(image->getWidth()), static_cast<GLsizei>(image->getHeight()),
    192                  Format(image->getFormat()), 0, MultisamplingMode::Regular,
    193                  image->sourceInitState());
    194    mState.setProtectedContent(image->hasProtectedContent());
    195 
    196    onStateChange(angle::SubjectMessage::SubjectChanged);
    197 
    198    return angle::Result::Continue;
    199 }
    200 
    201 angle::Result Renderbuffer::copyRenderbufferSubData(Context *context,
    202                                                    const gl::Renderbuffer *srcBuffer,
    203                                                    GLint srcLevel,
    204                                                    GLint srcX,
    205                                                    GLint srcY,
    206                                                    GLint srcZ,
    207                                                    GLint dstLevel,
    208                                                    GLint dstX,
    209                                                    GLint dstY,
    210                                                    GLint dstZ,
    211                                                    GLsizei srcWidth,
    212                                                    GLsizei srcHeight,
    213                                                    GLsizei srcDepth)
    214 {
    215    ANGLE_TRY(mImplementation->copyRenderbufferSubData(context, srcBuffer, srcLevel, srcX, srcY,
    216                                                       srcZ, dstLevel, dstX, dstY, dstZ, srcWidth,
    217                                                       srcHeight, srcDepth));
    218 
    219    return angle::Result::Continue;
    220 }
    221 
    222 angle::Result Renderbuffer::copyTextureSubData(Context *context,
    223                                               const gl::Texture *srcTexture,
    224                                               GLint srcLevel,
    225                                               GLint srcX,
    226                                               GLint srcY,
    227                                               GLint srcZ,
    228                                               GLint dstLevel,
    229                                               GLint dstX,
    230                                               GLint dstY,
    231                                               GLint dstZ,
    232                                               GLsizei srcWidth,
    233                                               GLsizei srcHeight,
    234                                               GLsizei srcDepth)
    235 {
    236    ANGLE_TRY(mImplementation->copyTextureSubData(context, srcTexture, srcLevel, srcX, srcY, srcZ,
    237                                                  dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight,
    238                                                  srcDepth));
    239 
    240    return angle::Result::Continue;
    241 }
    242 
    243 rx::RenderbufferImpl *Renderbuffer::getImplementation() const
    244 {
    245    ASSERT(mImplementation);
    246    return mImplementation.get();
    247 }
    248 
    249 GLsizei Renderbuffer::getWidth() const
    250 {
    251    return mState.mWidth;
    252 }
    253 
    254 GLsizei Renderbuffer::getHeight() const
    255 {
    256    return mState.mHeight;
    257 }
    258 
    259 const Format &Renderbuffer::getFormat() const
    260 {
    261    return mState.mFormat;
    262 }
    263 
    264 GLsizei Renderbuffer::getSamples() const
    265 {
    266    return mState.mMultisamplingMode == MultisamplingMode::Regular ? mState.mSamples : 0;
    267 }
    268 
    269 MultisamplingMode Renderbuffer::getMultisamplingMode() const
    270 {
    271    return mState.mMultisamplingMode;
    272 }
    273 
    274 GLuint Renderbuffer::getRedSize() const
    275 {
    276    return mState.mFormat.info->redBits;
    277 }
    278 
    279 GLuint Renderbuffer::getGreenSize() const
    280 {
    281    return mState.mFormat.info->greenBits;
    282 }
    283 
    284 GLuint Renderbuffer::getBlueSize() const
    285 {
    286    return mState.mFormat.info->blueBits;
    287 }
    288 
    289 GLuint Renderbuffer::getAlphaSize() const
    290 {
    291    return mState.mFormat.info->alphaBits;
    292 }
    293 
    294 GLuint Renderbuffer::getDepthSize() const
    295 {
    296    return mState.mFormat.info->depthBits;
    297 }
    298 
    299 GLuint Renderbuffer::getStencilSize() const
    300 {
    301    return mState.mFormat.info->stencilBits;
    302 }
    303 
    304 const RenderbufferState &Renderbuffer::getState() const
    305 {
    306    return mState;
    307 }
    308 
    309 GLint Renderbuffer::getMemorySize() const
    310 {
    311    GLint implSize = mImplementation->getMemorySize();
    312    if (implSize > 0)
    313    {
    314        return implSize;
    315    }
    316 
    317    // Assume allocated size is around width * height * samples * pixelBytes
    318    angle::CheckedNumeric<GLint> size = 1;
    319    size *= mState.mFormat.info->pixelBytes;
    320    size *= mState.mWidth;
    321    size *= mState.mHeight;
    322    size *= std::max(mState.mSamples, 1);
    323    return size.ValueOrDefault(std::numeric_limits<GLint>::max());
    324 }
    325 
    326 void Renderbuffer::onAttach(const Context *context, rx::Serial framebufferSerial)
    327 {
    328    addRef();
    329 }
    330 
    331 void Renderbuffer::onDetach(const Context *context, rx::Serial framebufferSerial)
    332 {
    333    release(context);
    334 }
    335 
    336 GLuint Renderbuffer::getId() const
    337 {
    338    return id().value;
    339 }
    340 
    341 Extents Renderbuffer::getAttachmentSize(const gl::ImageIndex & /*imageIndex*/) const
    342 {
    343    return Extents(mState.mWidth, mState.mHeight, 1);
    344 }
    345 
    346 Format Renderbuffer::getAttachmentFormat(GLenum /*binding*/,
    347                                         const ImageIndex & /*imageIndex*/) const
    348 {
    349    return getFormat();
    350 }
    351 GLsizei Renderbuffer::getAttachmentSamples(const ImageIndex & /*imageIndex*/) const
    352 {
    353    return getSamples();
    354 }
    355 
    356 bool Renderbuffer::isRenderable(const Context *context,
    357                                GLenum binding,
    358                                const ImageIndex &imageIndex) const
    359 {
    360    if (isEGLImageTarget())
    361    {
    362        return ImageSibling::isRenderable(context, binding, imageIndex);
    363    }
    364    return getFormat().info->renderbufferSupport(context->getClientVersion(),
    365                                                 context->getExtensions());
    366 }
    367 
    368 InitState Renderbuffer::initState(GLenum /*binding*/, const gl::ImageIndex & /*imageIndex*/) const
    369 {
    370    if (isEGLImageTarget())
    371    {
    372        return sourceEGLImageInitState();
    373    }
    374 
    375    return mState.mInitState;
    376 }
    377 
    378 void Renderbuffer::setInitState(GLenum /*binding*/,
    379                                const gl::ImageIndex & /*imageIndex*/,
    380                                InitState initState)
    381 {
    382    if (isEGLImageTarget())
    383    {
    384        setSourceEGLImageInitState(initState);
    385    }
    386    else
    387    {
    388        mState.mInitState = initState;
    389    }
    390 }
    391 
    392 rx::FramebufferAttachmentObjectImpl *Renderbuffer::getAttachmentImpl() const
    393 {
    394    return mImplementation.get();
    395 }
    396 
    397 GLenum Renderbuffer::getImplementationColorReadFormat(const Context *context) const
    398 {
    399    return mImplementation->getColorReadFormat(context);
    400 }
    401 
    402 GLenum Renderbuffer::getImplementationColorReadType(const Context *context) const
    403 {
    404    return mImplementation->getColorReadType(context);
    405 }
    406 
    407 angle::Result Renderbuffer::getRenderbufferImage(const Context *context,
    408                                                 const PixelPackState &packState,
    409                                                 Buffer *packBuffer,
    410                                                 GLenum format,
    411                                                 GLenum type,
    412                                                 void *pixels) const
    413 {
    414    return mImplementation->getRenderbufferImage(context, packState, packBuffer, format, type,
    415                                                 pixels);
    416 }
    417 
    418 void Renderbuffer::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
    419 {
    420    ASSERT(message == angle::SubjectMessage::SubjectChanged);
    421    onStateChange(angle::SubjectMessage::ContentsChanged);
    422 }
    423 }  // namespace gl