• 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 // 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 // RenderbufferState implementation.
RenderbufferState()26 RenderbufferState::RenderbufferState()
27     : mWidth(0), mHeight(0), mFormat(GL_RGBA4), mSamples(0), mInitState(InitState::MayNeedInit)
28 {}
29 
~RenderbufferState()30 RenderbufferState::~RenderbufferState() {}
31 
getWidth() const32 GLsizei RenderbufferState::getWidth() const
33 {
34     return mWidth;
35 }
36 
getHeight() const37 GLsizei RenderbufferState::getHeight() const
38 {
39     return mHeight;
40 }
41 
getFormat() const42 const Format &RenderbufferState::getFormat() const
43 {
44     return mFormat;
45 }
46 
getSamples() const47 GLsizei RenderbufferState::getSamples() const
48 {
49     return mSamples;
50 }
51 
update(GLsizei width,GLsizei height,const Format & format,GLsizei samples,InitState initState)52 void RenderbufferState::update(GLsizei width,
53                                GLsizei height,
54                                const Format &format,
55                                GLsizei samples,
56                                InitState initState)
57 {
58     mWidth     = static_cast<GLsizei>(width);
59     mHeight    = static_cast<GLsizei>(height);
60     mFormat    = format;
61     mSamples   = samples;
62     mInitState = InitState::MayNeedInit;
63 }
64 
65 // Renderbuffer implementation.
Renderbuffer(rx::GLImplFactory * implFactory,RenderbufferID id)66 Renderbuffer::Renderbuffer(rx::GLImplFactory *implFactory, RenderbufferID id)
67     : RefCountObject(id.value),
68       mState(),
69       mImplementation(implFactory->createRenderbuffer(mState)),
70       mLabel()
71 {}
72 
onDestroy(const Context * context)73 void Renderbuffer::onDestroy(const Context *context)
74 {
75     (void)(orphanImages(context));
76 
77     if (mImplementation)
78     {
79         mImplementation->onDestroy(context);
80     }
81 }
82 
~Renderbuffer()83 Renderbuffer::~Renderbuffer() {}
84 
setLabel(const Context * context,const std::string & label)85 void Renderbuffer::setLabel(const Context *context, const std::string &label)
86 {
87     mLabel = label;
88 }
89 
getLabel() const90 const std::string &Renderbuffer::getLabel() const
91 {
92     return mLabel;
93 }
94 
setStorage(const Context * context,GLenum internalformat,size_t width,size_t height)95 angle::Result Renderbuffer::setStorage(const Context *context,
96                                        GLenum internalformat,
97                                        size_t width,
98                                        size_t height)
99 {
100     ANGLE_TRY(orphanImages(context));
101     ANGLE_TRY(mImplementation->setStorage(context, internalformat, width, height));
102 
103     mState.update(static_cast<GLsizei>(width), static_cast<GLsizei>(height), Format(internalformat),
104                   0, InitState::MayNeedInit);
105     onStateChange(angle::SubjectMessage::SubjectChanged);
106 
107     return angle::Result::Continue;
108 }
109 
setStorageMultisample(const Context * context,size_t samples,GLenum internalformat,size_t width,size_t height)110 angle::Result Renderbuffer::setStorageMultisample(const Context *context,
111                                                   size_t samples,
112                                                   GLenum internalformat,
113                                                   size_t width,
114                                                   size_t height)
115 {
116     ANGLE_TRY(orphanImages(context));
117     ANGLE_TRY(
118         mImplementation->setStorageMultisample(context, samples, internalformat, width, height));
119 
120     mState.update(static_cast<GLsizei>(width), static_cast<GLsizei>(height), Format(internalformat),
121                   static_cast<GLsizei>(samples), InitState::MayNeedInit);
122     onStateChange(angle::SubjectMessage::SubjectChanged);
123 
124     return angle::Result::Continue;
125 }
126 
setStorageEGLImageTarget(const Context * context,egl::Image * image)127 angle::Result Renderbuffer::setStorageEGLImageTarget(const Context *context, egl::Image *image)
128 {
129     ANGLE_TRY(orphanImages(context));
130     ANGLE_TRY(mImplementation->setStorageEGLImageTarget(context, image));
131 
132     setTargetImage(context, image);
133 
134     mState.update(static_cast<GLsizei>(image->getWidth()), static_cast<GLsizei>(image->getHeight()),
135                   Format(image->getFormat()), 0, image->sourceInitState());
136     onStateChange(angle::SubjectMessage::SubjectChanged);
137 
138     return angle::Result::Continue;
139 }
140 
getImplementation() const141 rx::RenderbufferImpl *Renderbuffer::getImplementation() const
142 {
143     ASSERT(mImplementation);
144     return mImplementation.get();
145 }
146 
getWidth() const147 GLsizei Renderbuffer::getWidth() const
148 {
149     return mState.mWidth;
150 }
151 
getHeight() const152 GLsizei Renderbuffer::getHeight() const
153 {
154     return mState.mHeight;
155 }
156 
getFormat() const157 const Format &Renderbuffer::getFormat() const
158 {
159     return mState.mFormat;
160 }
161 
getSamples() const162 GLsizei Renderbuffer::getSamples() const
163 {
164     return mState.mSamples;
165 }
166 
getRedSize() const167 GLuint Renderbuffer::getRedSize() const
168 {
169     return mState.mFormat.info->redBits;
170 }
171 
getGreenSize() const172 GLuint Renderbuffer::getGreenSize() const
173 {
174     return mState.mFormat.info->greenBits;
175 }
176 
getBlueSize() const177 GLuint Renderbuffer::getBlueSize() const
178 {
179     return mState.mFormat.info->blueBits;
180 }
181 
getAlphaSize() const182 GLuint Renderbuffer::getAlphaSize() const
183 {
184     return mState.mFormat.info->alphaBits;
185 }
186 
getDepthSize() const187 GLuint Renderbuffer::getDepthSize() const
188 {
189     return mState.mFormat.info->depthBits;
190 }
191 
getStencilSize() const192 GLuint Renderbuffer::getStencilSize() const
193 {
194     return mState.mFormat.info->stencilBits;
195 }
196 
getMemorySize() const197 GLint Renderbuffer::getMemorySize() const
198 {
199     GLint implSize = mImplementation->getMemorySize();
200     if (implSize > 0)
201     {
202         return implSize;
203     }
204 
205     // Assume allocated size is around width * height * samples * pixelBytes
206     angle::CheckedNumeric<GLint> size = 1;
207     size *= mState.mFormat.info->pixelBytes;
208     size *= mState.mWidth;
209     size *= mState.mHeight;
210     size *= std::max(mState.mSamples, 1);
211     return size.ValueOrDefault(std::numeric_limits<GLint>::max());
212 }
213 
onAttach(const Context * context)214 void Renderbuffer::onAttach(const Context *context)
215 {
216     addRef();
217 }
218 
onDetach(const Context * context)219 void Renderbuffer::onDetach(const Context *context)
220 {
221     release(context);
222 }
223 
getId() const224 GLuint Renderbuffer::getId() const
225 {
226     return id();
227 }
228 
getAttachmentSize(const gl::ImageIndex &) const229 Extents Renderbuffer::getAttachmentSize(const gl::ImageIndex & /*imageIndex*/) const
230 {
231     return Extents(mState.mWidth, mState.mHeight, 1);
232 }
233 
getAttachmentFormat(GLenum,const ImageIndex &) const234 Format Renderbuffer::getAttachmentFormat(GLenum /*binding*/,
235                                          const ImageIndex & /*imageIndex*/) const
236 {
237     return getFormat();
238 }
getAttachmentSamples(const ImageIndex &) const239 GLsizei Renderbuffer::getAttachmentSamples(const ImageIndex & /*imageIndex*/) const
240 {
241     return getSamples();
242 }
243 
isRenderable(const Context * context,GLenum binding,const ImageIndex & imageIndex) const244 bool Renderbuffer::isRenderable(const Context *context,
245                                 GLenum binding,
246                                 const ImageIndex &imageIndex) const
247 {
248     if (isEGLImageTarget())
249     {
250         return ImageSibling::isRenderable(context, binding, imageIndex);
251     }
252     return getFormat().info->renderbufferSupport(context->getClientVersion(),
253                                                  context->getExtensions());
254 }
255 
initState(const gl::ImageIndex &) const256 InitState Renderbuffer::initState(const gl::ImageIndex & /*imageIndex*/) const
257 {
258     if (isEGLImageTarget())
259     {
260         return sourceEGLImageInitState();
261     }
262 
263     return mState.mInitState;
264 }
265 
setInitState(const gl::ImageIndex &,InitState initState)266 void Renderbuffer::setInitState(const gl::ImageIndex & /*imageIndex*/, InitState initState)
267 {
268     if (isEGLImageTarget())
269     {
270         setSourceEGLImageInitState(initState);
271     }
272     else
273     {
274         mState.mInitState = initState;
275     }
276 }
277 
getAttachmentImpl() const278 rx::FramebufferAttachmentObjectImpl *Renderbuffer::getAttachmentImpl() const
279 {
280     return mImplementation.get();
281 }
282 
283 }  // namespace gl
284