|  | /* | 
|  | * Copyright (C) 2013 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  |  | 
|  | #ifndef ANDROID_HWUI_RENDER_BUFFER_H | 
|  | #define ANDROID_HWUI_RENDER_BUFFER_H | 
|  |  | 
|  | #include <GLES2/gl2.h> | 
|  | #include <GLES2/gl2ext.h> | 
|  |  | 
|  | namespace android { | 
|  | namespace uirenderer { | 
|  |  | 
|  | /** | 
|  | * Represents an OpenGL render buffer. Render buffers are attached | 
|  | * to layers to perform stencil work. | 
|  | */ | 
|  | struct RenderBuffer { | 
|  | /** | 
|  | * Creates a new render buffer in the specified format and dimensions. | 
|  | * The format must be one of the formats allowed by glRenderbufferStorage(). | 
|  | */ | 
|  | RenderBuffer(GLenum format, uint32_t width, uint32_t height): | 
|  | mFormat(format), mWidth(width), mHeight(height), mAllocated(false) { | 
|  |  | 
|  | glGenRenderbuffers(1, &mName); | 
|  | } | 
|  |  | 
|  | ~RenderBuffer() { | 
|  | if (mName) { | 
|  | glDeleteRenderbuffers(1, &mName); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Returns the GL name of this render buffer. | 
|  | */ | 
|  | GLuint getName() const { | 
|  | return mName; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Returns the format of this render buffer. | 
|  | */ | 
|  | GLenum getFormat() const { | 
|  | return mFormat; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Binds this render buffer to the current GL context. | 
|  | */ | 
|  | void bind() const { | 
|  | glBindRenderbuffer(GL_RENDERBUFFER, mName); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Indicates whether this render buffer has allocated its | 
|  | * storage. See allocate() and resize(). | 
|  | */ | 
|  | bool isAllocated() const { | 
|  | return mAllocated; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Allocates this render buffer's storage if needed. | 
|  | * This method doesn't do anything if isAllocated() returns true. | 
|  | */ | 
|  | void allocate() { | 
|  | if (!mAllocated) { | 
|  | glRenderbufferStorage(GL_RENDERBUFFER, mFormat, mWidth, mHeight); | 
|  | mAllocated = true; | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Resizes this render buffer. If the buffer was previously allocated, | 
|  | * the storage is re-allocated wit the new specified dimensions. If the | 
|  | * buffer wasn't previously allocated, the buffer remains unallocated. | 
|  | */ | 
|  | void resize(uint32_t width, uint32_t height) { | 
|  | if (isAllocated() && (width != mWidth || height != mHeight)) { | 
|  | glRenderbufferStorage(GL_RENDERBUFFER, mFormat, width, height); | 
|  | } | 
|  |  | 
|  | mWidth = width; | 
|  | mHeight = height; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Returns the width of the render buffer in pixels. | 
|  | */ | 
|  | uint32_t getWidth() const { | 
|  | return mWidth; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Returns the height of the render buffer in pixels. | 
|  | */ | 
|  | uint32_t getHeight() const { | 
|  | return mHeight; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Returns the size of this render buffer in bytes. | 
|  | */ | 
|  | uint32_t getSize() const { | 
|  | // Round to the nearest byte | 
|  | return (uint32_t) ((mWidth * mHeight * formatSize(mFormat)) / 8.0f + 0.5f); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Returns the number of bits per component in the specified format. | 
|  | * The format must be one of the formats allowed by glRenderbufferStorage(). | 
|  | */ | 
|  | static uint32_t formatSize(GLenum format) { | 
|  | switch (format) { | 
|  | case GL_STENCIL_INDEX8: | 
|  | return 8; | 
|  | case GL_STENCIL_INDEX1_OES: | 
|  | return 1; | 
|  | case GL_STENCIL_INDEX4_OES: | 
|  | return 4; | 
|  | case GL_DEPTH_COMPONENT16: | 
|  | case GL_RGBA4: | 
|  | case GL_RGB565: | 
|  | case GL_RGB5_A1: | 
|  | return 16; | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Indicates whether the specified format represents a stencil buffer. | 
|  | */ | 
|  | static bool isStencilBuffer(GLenum format) { | 
|  | switch (format) { | 
|  | case GL_STENCIL_INDEX8: | 
|  | case GL_STENCIL_INDEX1_OES: | 
|  | case GL_STENCIL_INDEX4_OES: | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Returns the name of the specified render buffer format. | 
|  | */ | 
|  | static const char* formatName(GLenum format) { | 
|  | switch (format) { | 
|  | case GL_STENCIL_INDEX8: | 
|  | return "STENCIL_8"; | 
|  | case GL_STENCIL_INDEX1_OES: | 
|  | return "STENCIL_1"; | 
|  | case GL_STENCIL_INDEX4_OES: | 
|  | return "STENCIL_4"; | 
|  | case GL_DEPTH_COMPONENT16: | 
|  | return "DEPTH_16"; | 
|  | case GL_RGBA4: | 
|  | return "RGBA_4444"; | 
|  | case GL_RGB565: | 
|  | return "RGB_565"; | 
|  | case GL_RGB5_A1: | 
|  | return "RGBA_5551"; | 
|  | } | 
|  | return "Unknown"; | 
|  | } | 
|  |  | 
|  | private: | 
|  | GLenum mFormat; | 
|  |  | 
|  | uint32_t mWidth; | 
|  | uint32_t mHeight; | 
|  |  | 
|  | bool mAllocated; | 
|  |  | 
|  | GLuint mName; | 
|  | }; // struct RenderBuffer | 
|  |  | 
|  | }; // namespace uirenderer | 
|  | }; // namespace android | 
|  |  | 
|  | #endif // ANDROID_HWUI_RENDER_BUFFER_H |