blob: 35a516a580220ea720d4900a6ac1edc4c2eb5122 [file] [log] [blame]
Romain Guy3bbacf22013-02-06 16:51:04 -08001/*
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
23namespace android {
24namespace uirenderer {
25
26/**
27 * Represents an OpenGL render buffer. Render buffers are attached
28 * to layers to perform stencil work.
29 */
30struct 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 */
35 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
41 ~RenderBuffer() {
Romain Guy8d4aeb72013-02-12 16:08:55 -080042 if (mName) {
Romain Guy3bbacf22013-02-06 16:51:04 -080043 glDeleteRenderbuffers(1, &mName);
44 }
45 }
46
47 /**
48 * Returns the GL name of this render buffer.
49 */
50 GLuint getName() const {
51 return mName;
52 }
53
54 /**
55 * Returns the format of this render buffer.
56 */
57 GLenum getFormat() const {
58 return mFormat;
59 }
60
61 /**
62 * Binds this render buffer to the current GL context.
63 */
64 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 */
72 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 */
80 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 */
92 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 */
104 uint32_t getWidth() const {
105 return mWidth;
106 }
107
108 /**
109 * Returns the height of the render buffer in pixels.
110 */
111 uint32_t getHeight() const {
112 return mHeight;
113 }
114
115 /**
116 * Returns the size of this render buffer in bytes.
117 */
118 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 */
127 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 */
147 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
Romain Guy8d4aeb72013-02-12 16:08:55 -0800157 /**
158 * Returns the name of the specified render buffer format.
159 */
160 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:
Romain Guy2b44eb72013-02-13 11:33:26 -0800171 return "RGBA_4444";
Romain Guy8d4aeb72013-02-12 16:08:55 -0800172 case GL_RGB565:
173 return "RGB_565";
174 case GL_RGB5_A1:
175 return "RGBA_5551";
176 }
177 return "Unknown";
178 }
179
Romain Guy3bbacf22013-02-06 16:51:04 -0800180private:
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