1 //
2 // Copyright 2015 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 // RenderbufferGL.cpp: Implements the class methods for RenderbufferGL.
8 
9 #include "libANGLE/renderer/gl/RenderbufferGL.h"
10 
11 #include "common/debug.h"
12 #include "libANGLE/Caps.h"
13 #include "libANGLE/Context.h"
14 #include "libANGLE/angletypes.h"
15 #include "libANGLE/renderer/gl/BlitGL.h"
16 #include "libANGLE/renderer/gl/ContextGL.h"
17 #include "libANGLE/renderer/gl/FunctionsGL.h"
18 #include "libANGLE/renderer/gl/ImageGL.h"
19 #include "libANGLE/renderer/gl/StateManagerGL.h"
20 #include "libANGLE/renderer/gl/formatutilsgl.h"
21 #include "libANGLE/renderer/gl/renderergl_utils.h"
22 #include "platform/FeaturesGL.h"
23 
24 namespace rx
25 {
RenderbufferGL(const gl::RenderbufferState & state,GLuint id)26 RenderbufferGL::RenderbufferGL(const gl::RenderbufferState &state, GLuint id)
27     : RenderbufferImpl(state), mRenderbufferID(id)
28 {}
29 
~RenderbufferGL()30 RenderbufferGL::~RenderbufferGL()
31 {
32     ASSERT(mRenderbufferID == 0);
33 }
34 
onDestroy(const gl::Context * context)35 void RenderbufferGL::onDestroy(const gl::Context *context)
36 {
37     StateManagerGL *stateManager = GetStateManagerGL(context);
38     stateManager->deleteRenderbuffer(mRenderbufferID);
39     mRenderbufferID = 0;
40 }
41 
setStorage(const gl::Context * context,GLenum internalformat,GLsizei width,GLsizei height)42 angle::Result RenderbufferGL::setStorage(const gl::Context *context,
43                                          GLenum internalformat,
44                                          GLsizei width,
45                                          GLsizei height)
46 {
47     const FunctionsGL *functions      = GetFunctionsGL(context);
48     StateManagerGL *stateManager      = GetStateManagerGL(context);
49     const angle::FeaturesGL &features = GetFeaturesGL(context);
50 
51     stateManager->bindRenderbuffer(GL_RENDERBUFFER, mRenderbufferID);
52 
53     nativegl::RenderbufferFormat renderbufferFormat =
54         nativegl::GetRenderbufferFormat(functions, features, internalformat);
55     ANGLE_GL_TRY_ALWAYS_CHECK(
56         context, functions->renderbufferStorage(GL_RENDERBUFFER, renderbufferFormat.internalFormat,
57                                                 width, height));
58 
59     mNativeInternalFormat = renderbufferFormat.internalFormat;
60 
61     return angle::Result::Continue;
62 }
63 
setStorageMultisample(const gl::Context * context,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,gl::MultisamplingMode mode)64 angle::Result RenderbufferGL::setStorageMultisample(const gl::Context *context,
65                                                     GLsizei samples,
66                                                     GLenum internalformat,
67                                                     GLsizei width,
68                                                     GLsizei height,
69                                                     gl::MultisamplingMode mode)
70 {
71     const FunctionsGL *functions      = GetFunctionsGL(context);
72     StateManagerGL *stateManager      = GetStateManagerGL(context);
73     const angle::FeaturesGL &features = GetFeaturesGL(context);
74 
75     stateManager->bindRenderbuffer(GL_RENDERBUFFER, mRenderbufferID);
76 
77     nativegl::RenderbufferFormat renderbufferFormat =
78         nativegl::GetRenderbufferFormat(functions, features, internalformat);
79     if (mode == gl::MultisamplingMode::Regular)
80     {
81         ANGLE_GL_TRY_ALWAYS_CHECK(context, functions->renderbufferStorageMultisample(
82                                                GL_RENDERBUFFER, samples,
83                                                renderbufferFormat.internalFormat, width, height));
84     }
85     else
86     {
87         ASSERT(mode == gl::MultisamplingMode::MultisampledRenderToTexture);
88 
89         if (functions->renderbufferStorageMultisampleEXT)
90         {
91             ANGLE_GL_TRY_ALWAYS_CHECK(
92                 context,
93                 functions->renderbufferStorageMultisampleEXT(
94                     GL_RENDERBUFFER, samples, renderbufferFormat.internalFormat, width, height));
95         }
96         else
97         {
98             ASSERT(functions->renderbufferStorageMultisampleIMG);
99             ANGLE_GL_TRY_ALWAYS_CHECK(
100                 context,
101                 functions->renderbufferStorageMultisampleIMG(
102                     GL_RENDERBUFFER, samples, renderbufferFormat.internalFormat, width, height));
103         }
104     }
105 
106     mNativeInternalFormat = renderbufferFormat.internalFormat;
107 
108     return angle::Result::Continue;
109 }
110 
setStorageEGLImageTarget(const gl::Context * context,egl::Image * image)111 angle::Result RenderbufferGL::setStorageEGLImageTarget(const gl::Context *context,
112                                                        egl::Image *image)
113 {
114     ImageGL *imageGL = GetImplAs<ImageGL>(image);
115     return imageGL->setRenderbufferStorage(context, this, &mNativeInternalFormat);
116 }
117 
getRenderbufferID() const118 GLuint RenderbufferGL::getRenderbufferID() const
119 {
120     return mRenderbufferID;
121 }
122 
initializeContents(const gl::Context * context,const gl::ImageIndex & imageIndex)123 angle::Result RenderbufferGL::initializeContents(const gl::Context *context,
124                                                  const gl::ImageIndex &imageIndex)
125 {
126     BlitGL *blitter = GetBlitGL(context);
127     return blitter->clearRenderbuffer(context, this, mNativeInternalFormat);
128 }
129 
getNativeInternalFormat() const130 GLenum RenderbufferGL::getNativeInternalFormat() const
131 {
132     return mNativeInternalFormat;
133 }
134 
135 }  // namespace rx
136