1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ANDROID_HWUI_RENDER_BUFFER_H
18 #define ANDROID_HWUI_RENDER_BUFFER_H
19 
20 #include <GLES2/gl2.h>
21 #include <GLES2/gl2ext.h>
22 
23 namespace android {
24 namespace uirenderer {
25 
26 /**
27  * Represents an OpenGL render buffer. Render buffers are attached
28  * to layers to perform stencil work.
29  */
30 struct RenderBuffer {
31     /**
32      * Creates a new render buffer in the specified format and dimensions.
33      * The format must be one of the formats allowed by glRenderbufferStorage().
34      */
RenderBufferRenderBuffer35     RenderBuffer(GLenum format, uint32_t width, uint32_t height):
36         mFormat(format), mWidth(width), mHeight(height), mAllocated(false) {
37 
38         glGenRenderbuffers(1, &mName);
39     }
40 
~RenderBufferRenderBuffer41     ~RenderBuffer() {
42         if (mName) {
43             glDeleteRenderbuffers(1, &mName);
44         }
45     }
46 
47     /**
48      * Returns the GL name of this render buffer.
49      */
getNameRenderBuffer50     GLuint getName() const {
51         return mName;
52     }
53 
54     /**
55      * Returns the format of this render buffer.
56      */
getFormatRenderBuffer57     GLenum getFormat() const {
58         return mFormat;
59     }
60 
61     /**
62      * Binds this render buffer to the current GL context.
63      */
bindRenderBuffer64     void bind() const {
65         glBindRenderbuffer(GL_RENDERBUFFER, mName);
66     }
67 
68     /**
69      * Indicates whether this render buffer has allocated its
70      * storage. See allocate() and resize().
71      */
isAllocatedRenderBuffer72     bool isAllocated() const {
73         return mAllocated;
74     }
75 
76     /**
77      * Allocates this render buffer's storage if needed.
78      * This method doesn't do anything if isAllocated() returns true.
79      */
allocateRenderBuffer80     void allocate() {
81         if (!mAllocated) {
82             glRenderbufferStorage(GL_RENDERBUFFER, mFormat, mWidth, mHeight);
83             mAllocated = true;
84         }
85     }
86 
87     /**
88      * Resizes this render buffer. If the buffer was previously allocated,
89      * the storage is re-allocated wit the new specified dimensions. If the
90      * buffer wasn't previously allocated, the buffer remains unallocated.
91      */
resizeRenderBuffer92     void resize(uint32_t width, uint32_t height) {
93         if (isAllocated() && (width != mWidth || height != mHeight)) {
94             glRenderbufferStorage(GL_RENDERBUFFER, mFormat, width, height);
95         }
96 
97         mWidth = width;
98         mHeight = height;
99     }
100 
101     /**
102      * Returns the width of the render buffer in pixels.
103      */
getWidthRenderBuffer104     uint32_t getWidth() const {
105         return mWidth;
106     }
107 
108     /**
109      * Returns the height of the render buffer in pixels.
110      */
getHeightRenderBuffer111     uint32_t getHeight() const {
112         return mHeight;
113     }
114 
115     /**
116      * Returns the size of this render buffer in bytes.
117      */
getSizeRenderBuffer118     uint32_t getSize() const {
119         // Round to the nearest byte
120         return (uint32_t) ((mWidth * mHeight * formatSize(mFormat)) / 8.0f + 0.5f);
121     }
122 
123     /**
124      * Returns the number of bits per component in the specified format.
125      * The format must be one of the formats allowed by glRenderbufferStorage().
126      */
formatSizeRenderBuffer127     static uint32_t formatSize(GLenum format) {
128         switch (format) {
129             case GL_STENCIL_INDEX8:
130                 return 8;
131             case GL_STENCIL_INDEX1_OES:
132                 return 1;
133             case GL_STENCIL_INDEX4_OES:
134                 return 4;
135             case GL_DEPTH_COMPONENT16:
136             case GL_RGBA4:
137             case GL_RGB565:
138             case GL_RGB5_A1:
139                 return 16;
140         }
141         return 0;
142     }
143 
144     /**
145      * Indicates whether the specified format represents a stencil buffer.
146      */
isStencilBufferRenderBuffer147     static bool isStencilBuffer(GLenum format) {
148         switch (format) {
149             case GL_STENCIL_INDEX8:
150             case GL_STENCIL_INDEX1_OES:
151             case GL_STENCIL_INDEX4_OES:
152                 return true;
153         }
154         return false;
155     }
156 
157     /**
158      * Returns the name of the specified render buffer format.
159      */
formatNameRenderBuffer160     static const char* formatName(GLenum format) {
161         switch (format) {
162             case GL_STENCIL_INDEX8:
163                 return "STENCIL_8";
164             case GL_STENCIL_INDEX1_OES:
165                 return "STENCIL_1";
166             case GL_STENCIL_INDEX4_OES:
167                 return "STENCIL_4";
168             case GL_DEPTH_COMPONENT16:
169                 return "DEPTH_16";
170             case GL_RGBA4:
171                 return "RGBA_4444";
172             case GL_RGB565:
173                 return "RGB_565";
174             case GL_RGB5_A1:
175                 return "RGBA_5551";
176         }
177         return "Unknown";
178     }
179 
180 private:
181     GLenum mFormat;
182 
183     uint32_t mWidth;
184     uint32_t mHeight;
185 
186     bool mAllocated;
187 
188     GLuint mName;
189 }; // struct RenderBuffer
190 
191 }; // namespace uirenderer
192 }; // namespace android
193 
194 #endif // ANDROID_HWUI_RENDER_BUFFER_H
195