| /* |
| * 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 |