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