summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/libANGLE/Renderbuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/libANGLE/Renderbuffer.cpp')
-rw-r--r--gfx/angle/checkout/src/libANGLE/Renderbuffer.cpp423
1 files changed, 423 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/libANGLE/Renderbuffer.cpp b/gfx/angle/checkout/src/libANGLE/Renderbuffer.cpp
new file mode 100644
index 0000000000..ce2445c31e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Renderbuffer.cpp
@@ -0,0 +1,423 @@
+//
+// 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;
+
+InitState DetermineInitState(const Context *context)
+{
+ return (context && context->isRobustResourceInitEnabled()) ? InitState::MayNeedInit
+ : InitState::Initialized;
+}
+} // namespace
+
+// RenderbufferState implementation.
+RenderbufferState::RenderbufferState()
+ : mWidth(0),
+ mHeight(0),
+ mFormat(GL_RGBA4),
+ mSamples(0),
+ mMultisamplingMode(MultisamplingMode::Regular),
+ mHasProtectedContent(false),
+ mInitState(InitState::Initialized)
+{}
+
+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;
+}
+
+MultisamplingMode RenderbufferState::getMultisamplingMode() const
+{
+ return mMultisamplingMode;
+}
+
+InitState RenderbufferState::getInitState() const
+{
+ return mInitState;
+}
+
+void RenderbufferState::update(GLsizei width,
+ GLsizei height,
+ const Format &format,
+ GLsizei samples,
+ MultisamplingMode multisamplingMode,
+ InitState initState)
+{
+ mWidth = width;
+ mHeight = height;
+ mFormat = format;
+ mSamples = samples;
+ mMultisamplingMode = multisamplingMode;
+ mInitState = initState;
+ mHasProtectedContent = false;
+}
+
+void RenderbufferState::setProtectedContent(bool hasProtectedContent)
+{
+ mHasProtectedContent = hasProtectedContent;
+}
+
+// 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)
+{
+ egl::RefCountObjectReleaser<egl::Image> releaseImage;
+ (void)orphanImages(context, &releaseImage);
+
+ if (mImplementation)
+ {
+ mImplementation->onDestroy(context);
+ }
+}
+
+Renderbuffer::~Renderbuffer() {}
+
+angle::Result Renderbuffer::setLabel(const Context *context, const std::string &label)
+{
+ mLabel = label;
+
+ if (mImplementation)
+ {
+ return mImplementation->onLabelUpdate(context);
+ }
+ return angle::Result::Continue;
+}
+
+const std::string &Renderbuffer::getLabel() const
+{
+ return mLabel;
+}
+
+angle::Result Renderbuffer::setStorage(const Context *context,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+
+ egl::RefCountObjectReleaser<egl::Image> releaseImage;
+ ANGLE_TRY(orphanImages(context, &releaseImage));
+
+ ANGLE_TRY(mImplementation->setStorage(context, internalformat, width, height));
+
+ mState.update(width, height, Format(internalformat), 0, MultisamplingMode::Regular,
+ DetermineInitState(context));
+ onStateChange(angle::SubjectMessage::SubjectChanged);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderbuffer::setStorageMultisample(const Context *context,
+ GLsizei samplesIn,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ MultisamplingMode mode)
+{
+ egl::RefCountObjectReleaser<egl::Image> releaseImage;
+ ANGLE_TRY(orphanImages(context, &releaseImage));
+
+ // Potentially adjust "samplesIn" to a supported value
+ const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
+ GLsizei samples = formatCaps.getNearestSamples(samplesIn);
+
+ ANGLE_TRY(mImplementation->setStorageMultisample(context, samples, internalformat, width,
+ height, mode));
+
+ mState.update(width, height, Format(internalformat), samples, mode,
+ DetermineInitState(context));
+ onStateChange(angle::SubjectMessage::SubjectChanged);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderbuffer::setStorageEGLImageTarget(const Context *context, egl::Image *image)
+{
+ egl::RefCountObjectReleaser<egl::Image> releaseImage;
+ ANGLE_TRY(orphanImages(context, &releaseImage));
+
+ 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, MultisamplingMode::Regular,
+ image->sourceInitState());
+ mState.setProtectedContent(image->hasProtectedContent());
+
+ onStateChange(angle::SubjectMessage::SubjectChanged);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderbuffer::copyRenderbufferSubData(Context *context,
+ const gl::Renderbuffer *srcBuffer,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ ANGLE_TRY(mImplementation->copyRenderbufferSubData(context, srcBuffer, srcLevel, srcX, srcY,
+ srcZ, dstLevel, dstX, dstY, dstZ, srcWidth,
+ srcHeight, srcDepth));
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderbuffer::copyTextureSubData(Context *context,
+ const gl::Texture *srcTexture,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ ANGLE_TRY(mImplementation->copyTextureSubData(context, srcTexture, srcLevel, srcX, srcY, srcZ,
+ dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight,
+ srcDepth));
+
+ 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.mMultisamplingMode == MultisamplingMode::Regular ? mState.mSamples : 0;
+}
+
+MultisamplingMode Renderbuffer::getMultisamplingMode() const
+{
+ return mState.mMultisamplingMode;
+}
+
+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, rx::Serial framebufferSerial)
+{
+ addRef();
+}
+
+void Renderbuffer::onDetach(const Context *context, rx::Serial framebufferSerial)
+{
+ 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(GLenum /*binding*/, const gl::ImageIndex & /*imageIndex*/) const
+{
+ if (isEGLImageTarget())
+ {
+ return sourceEGLImageInitState();
+ }
+
+ return mState.mInitState;
+}
+
+void Renderbuffer::setInitState(GLenum /*binding*/,
+ 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