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