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 glGenRenderbuffers(1, &mName); 38 } 39 ~RenderBufferRenderBuffer40 ~RenderBuffer() { 41 if (mName) { 42 glDeleteRenderbuffers(1, &mName); 43 } 44 } 45 46 /** 47 * Returns the GL name of this render buffer. 48 */ getNameRenderBuffer49 GLuint getName() const { return mName; } 50 51 /** 52 * Returns the format of this render buffer. 53 */ getFormatRenderBuffer54 GLenum getFormat() const { return mFormat; } 55 56 /** 57 * Binds this render buffer to the current GL context. 58 */ bindRenderBuffer59 void bind() const { glBindRenderbuffer(GL_RENDERBUFFER, mName); } 60 61 /** 62 * Indicates whether this render buffer has allocated its 63 * storage. See allocate() and resize(). 64 */ isAllocatedRenderBuffer65 bool isAllocated() const { return mAllocated; } 66 67 /** 68 * Allocates this render buffer's storage if needed. 69 * This method doesn't do anything if isAllocated() returns true. 70 */ allocateRenderBuffer71 void allocate() { 72 if (!mAllocated) { 73 glRenderbufferStorage(GL_RENDERBUFFER, mFormat, mWidth, mHeight); 74 mAllocated = true; 75 } 76 } 77 78 /** 79 * Resizes this render buffer. If the buffer was previously allocated, 80 * the storage is re-allocated wit the new specified dimensions. If the 81 * buffer wasn't previously allocated, the buffer remains unallocated. 82 */ resizeRenderBuffer83 void resize(uint32_t width, uint32_t height) { 84 if (isAllocated() && (width != mWidth || height != mHeight)) { 85 glRenderbufferStorage(GL_RENDERBUFFER, mFormat, width, height); 86 } 87 88 mWidth = width; 89 mHeight = height; 90 } 91 92 /** 93 * Returns the width of the render buffer in pixels. 94 */ getWidthRenderBuffer95 uint32_t getWidth() const { return mWidth; } 96 97 /** 98 * Returns the height of the render buffer in pixels. 99 */ getHeightRenderBuffer100 uint32_t getHeight() const { return mHeight; } 101 102 /** 103 * Returns the size of this render buffer in bytes. 104 */ getSizeRenderBuffer105 uint32_t getSize() const { 106 // Round to the nearest byte 107 return (uint32_t)((mWidth * mHeight * formatSize(mFormat)) / 8.0f + 0.5f); 108 } 109 110 /** 111 * Returns the number of bits per component in the specified format. 112 * The format must be one of the formats allowed by glRenderbufferStorage(). 113 */ formatSizeRenderBuffer114 static uint32_t formatSize(GLenum format) { 115 switch (format) { 116 case GL_STENCIL_INDEX8: 117 return 8; 118 case GL_STENCIL_INDEX1_OES: 119 return 1; 120 case GL_STENCIL_INDEX4_OES: 121 return 4; 122 case GL_DEPTH_COMPONENT16: 123 case GL_RGBA4: 124 case GL_RGB565: 125 case GL_RGB5_A1: 126 return 16; 127 } 128 return 0; 129 } 130 131 /** 132 * Indicates whether the specified format represents a stencil buffer. 133 */ isStencilBufferRenderBuffer134 static bool isStencilBuffer(GLenum format) { 135 switch (format) { 136 case GL_STENCIL_INDEX8: 137 case GL_STENCIL_INDEX1_OES: 138 case GL_STENCIL_INDEX4_OES: 139 return true; 140 } 141 return false; 142 } 143 144 /** 145 * Returns the name of the specified render buffer format. 146 */ formatNameRenderBuffer147 static const char* formatName(GLenum format) { 148 switch (format) { 149 case GL_STENCIL_INDEX8: 150 return "STENCIL_8"; 151 case GL_STENCIL_INDEX1_OES: 152 return "STENCIL_1"; 153 case GL_STENCIL_INDEX4_OES: 154 return "STENCIL_4"; 155 case GL_DEPTH_COMPONENT16: 156 return "DEPTH_16"; 157 case GL_RGBA4: 158 return "RGBA_4444"; 159 case GL_RGB565: 160 return "RGB_565"; 161 case GL_RGB5_A1: 162 return "RGBA_5551"; 163 } 164 return "Unknown"; 165 } 166 167 private: 168 GLenum mFormat; 169 170 uint32_t mWidth; 171 uint32_t mHeight; 172 173 bool mAllocated; 174 175 GLuint mName; 176 }; // struct RenderBuffer 177 178 }; // namespace uirenderer 179 }; // namespace android 180 181 #endif // ANDROID_HWUI_RENDER_BUFFER_H 182