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