Edit

kc3-lang/angle/src/libANGLE/Renderbuffer.cpp

Branch :

  • Show log

    Commit

  • Author : Manh Nguyen
    Date : 2020-07-29 13:52:28
    Hash : aca14d47
    Message : Add renderbuffer serialization capability Serializes renderbuffers' states stored on CPU. Gets renderbuffers content from GPU then serialize them. Adds renderbuffers serialization to serializeContext method so that capture replay regresssion testing now compares the states of renderbuffers too. Bug: angleproject:4817 Change-Id: I537b11ee85decb14eea461ebbd62ce6ab0402f85 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2327173 Commit-Queue: Manh Nguyen <nguyenmh@google.com> Reviewed-by: Cody Northrop <cnorthrop@google.com> Reviewed-by: Jamie Madill <jmadill@chromium.org>

  • src/libANGLE/Renderbuffer.cpp
  • //
    // Copyright 2002 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    
    // Renderbuffer.cpp: Implements the renderer-agnostic gl::Renderbuffer class,
    // GL renderbuffer objects and related functionality.
    // [OpenGL ES 2.0.24] section 4.4.3 page 108.
    
    #include "libANGLE/Renderbuffer.h"
    
    #include "common/utilities.h"
    #include "libANGLE/Context.h"
    #include "libANGLE/FramebufferAttachment.h"
    #include "libANGLE/Image.h"
    #include "libANGLE/Renderbuffer.h"
    #include "libANGLE/Texture.h"
    #include "libANGLE/formatutils.h"
    #include "libANGLE/renderer/GLImplFactory.h"
    #include "libANGLE/renderer/d3d/RenderTargetD3D.h"
    
    namespace gl
    {
    namespace
    {
    angle::SubjectIndex kRenderbufferImplSubjectIndex = 0;
    }  // namespace
    
    // RenderbufferState implementation.
    RenderbufferState::RenderbufferState()
        : mWidth(0), mHeight(0), mFormat(GL_RGBA4), mSamples(0), mInitState(InitState::MayNeedInit)
    {}
    
    RenderbufferState::~RenderbufferState() {}
    
    GLsizei RenderbufferState::getWidth() const
    {
        return mWidth;
    }
    
    GLsizei RenderbufferState::getHeight() const
    {
        return mHeight;
    }
    
    const Format &RenderbufferState::getFormat() const
    {
        return mFormat;
    }
    
    GLsizei RenderbufferState::getSamples() const
    {
        return mSamples;
    }
    
    InitState RenderbufferState::getInitState() const
    {
        return mInitState;
    }
    
    void RenderbufferState::update(GLsizei width,
                                   GLsizei height,
                                   const Format &format,
                                   GLsizei samples,
                                   InitState initState)
    {
        mWidth     = static_cast<GLsizei>(width);
        mHeight    = static_cast<GLsizei>(height);
        mFormat    = format;
        mSamples   = samples;
        mInitState = InitState::MayNeedInit;
    }
    
    // Renderbuffer implementation.
    Renderbuffer::Renderbuffer(rx::GLImplFactory *implFactory, RenderbufferID id)
        : RefCountObject(implFactory->generateSerial(), id),
          mState(),
          mImplementation(implFactory->createRenderbuffer(mState)),
          mLabel(),
          mImplObserverBinding(this, kRenderbufferImplSubjectIndex)
    {
        mImplObserverBinding.bind(mImplementation.get());
    }
    
    void Renderbuffer::onDestroy(const Context *context)
    {
        (void)(orphanImages(context));
    
        if (mImplementation)
        {
            mImplementation->onDestroy(context);
        }
    }
    
    Renderbuffer::~Renderbuffer() {}
    
    void Renderbuffer::setLabel(const Context *context, const std::string &label)
    {
        mLabel = label;
    }
    
    const std::string &Renderbuffer::getLabel() const
    {
        return mLabel;
    }
    
    angle::Result Renderbuffer::setStorage(const Context *context,
                                           GLenum internalformat,
                                           size_t width,
                                           size_t height)
    {
        ANGLE_TRY(orphanImages(context));
        ANGLE_TRY(mImplementation->setStorage(context, internalformat, width, height));
    
        mState.update(static_cast<GLsizei>(width), static_cast<GLsizei>(height), Format(internalformat),
                      0, InitState::MayNeedInit);
        onStateChange(angle::SubjectMessage::SubjectChanged);
    
        return angle::Result::Continue;
    }
    
    angle::Result Renderbuffer::setStorageMultisample(const Context *context,
                                                      size_t samples,
                                                      GLenum internalformat,
                                                      size_t width,
                                                      size_t height)
    {
        ANGLE_TRY(orphanImages(context));
    
        // Potentially adjust "samples" to a supported value
        const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
        samples                       = formatCaps.getNearestSamples(static_cast<GLuint>(samples));
    
        ANGLE_TRY(
            mImplementation->setStorageMultisample(context, samples, internalformat, width, height));
    
        mState.update(static_cast<GLsizei>(width), static_cast<GLsizei>(height), Format(internalformat),
                      static_cast<GLsizei>(samples), InitState::MayNeedInit);
        onStateChange(angle::SubjectMessage::SubjectChanged);
    
        return angle::Result::Continue;
    }
    
    angle::Result Renderbuffer::setStorageEGLImageTarget(const Context *context, egl::Image *image)
    {
        ANGLE_TRY(orphanImages(context));
        ANGLE_TRY(mImplementation->setStorageEGLImageTarget(context, image));
    
        setTargetImage(context, image);
    
        mState.update(static_cast<GLsizei>(image->getWidth()), static_cast<GLsizei>(image->getHeight()),
                      Format(image->getFormat()), 0, image->sourceInitState());
        onStateChange(angle::SubjectMessage::SubjectChanged);
    
        return angle::Result::Continue;
    }
    
    rx::RenderbufferImpl *Renderbuffer::getImplementation() const
    {
        ASSERT(mImplementation);
        return mImplementation.get();
    }
    
    GLsizei Renderbuffer::getWidth() const
    {
        return mState.mWidth;
    }
    
    GLsizei Renderbuffer::getHeight() const
    {
        return mState.mHeight;
    }
    
    const Format &Renderbuffer::getFormat() const
    {
        return mState.mFormat;
    }
    
    GLsizei Renderbuffer::getSamples() const
    {
        return mState.mSamples;
    }
    
    GLuint Renderbuffer::getRedSize() const
    {
        return mState.mFormat.info->redBits;
    }
    
    GLuint Renderbuffer::getGreenSize() const
    {
        return mState.mFormat.info->greenBits;
    }
    
    GLuint Renderbuffer::getBlueSize() const
    {
        return mState.mFormat.info->blueBits;
    }
    
    GLuint Renderbuffer::getAlphaSize() const
    {
        return mState.mFormat.info->alphaBits;
    }
    
    GLuint Renderbuffer::getDepthSize() const
    {
        return mState.mFormat.info->depthBits;
    }
    
    GLuint Renderbuffer::getStencilSize() const
    {
        return mState.mFormat.info->stencilBits;
    }
    
    const RenderbufferState &Renderbuffer::getState() const
    {
        return mState;
    }
    
    GLint Renderbuffer::getMemorySize() const
    {
        GLint implSize = mImplementation->getMemorySize();
        if (implSize > 0)
        {
            return implSize;
        }
    
        // Assume allocated size is around width * height * samples * pixelBytes
        angle::CheckedNumeric<GLint> size = 1;
        size *= mState.mFormat.info->pixelBytes;
        size *= mState.mWidth;
        size *= mState.mHeight;
        size *= std::max(mState.mSamples, 1);
        return size.ValueOrDefault(std::numeric_limits<GLint>::max());
    }
    
    void Renderbuffer::onAttach(const Context *context)
    {
        addRef();
    }
    
    void Renderbuffer::onDetach(const Context *context)
    {
        release(context);
    }
    
    GLuint Renderbuffer::getId() const
    {
        return id().value;
    }
    
    Extents Renderbuffer::getAttachmentSize(const gl::ImageIndex & /*imageIndex*/) const
    {
        return Extents(mState.mWidth, mState.mHeight, 1);
    }
    
    Format Renderbuffer::getAttachmentFormat(GLenum /*binding*/,
                                             const ImageIndex & /*imageIndex*/) const
    {
        return getFormat();
    }
    GLsizei Renderbuffer::getAttachmentSamples(const ImageIndex & /*imageIndex*/) const
    {
        return getSamples();
    }
    
    bool Renderbuffer::isRenderable(const Context *context,
                                    GLenum binding,
                                    const ImageIndex &imageIndex) const
    {
        if (isEGLImageTarget())
        {
            return ImageSibling::isRenderable(context, binding, imageIndex);
        }
        return getFormat().info->renderbufferSupport(context->getClientVersion(),
                                                     context->getExtensions());
    }
    
    InitState Renderbuffer::initState(const gl::ImageIndex & /*imageIndex*/) const
    {
        if (isEGLImageTarget())
        {
            return sourceEGLImageInitState();
        }
    
        return mState.mInitState;
    }
    
    void Renderbuffer::setInitState(const gl::ImageIndex & /*imageIndex*/, InitState initState)
    {
        if (isEGLImageTarget())
        {
            setSourceEGLImageInitState(initState);
        }
        else
        {
            mState.mInitState = initState;
        }
    }
    
    rx::FramebufferAttachmentObjectImpl *Renderbuffer::getAttachmentImpl() const
    {
        return mImplementation.get();
    }
    
    GLenum Renderbuffer::getImplementationColorReadFormat(const Context *context) const
    {
        return mImplementation->getColorReadFormat(context);
    }
    
    GLenum Renderbuffer::getImplementationColorReadType(const Context *context) const
    {
        return mImplementation->getColorReadType(context);
    }
    
    angle::Result Renderbuffer::getRenderbufferImage(const Context *context,
                                                     const PixelPackState &packState,
                                                     Buffer *packBuffer,
                                                     GLenum format,
                                                     GLenum type,
                                                     void *pixels) const
    {
        return mImplementation->getRenderbufferImage(context, packState, packBuffer, format, type,
                                                     pixels);
    }
    
    void Renderbuffer::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
    {
        ASSERT(message == angle::SubjectMessage::SubjectChanged);
        onStateChange(angle::SubjectMessage::ContentsChanged);
    }
    }  // namespace gl