13bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy/*
23bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * Copyright (C) 2013 The Android Open Source Project
33bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy *
43bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * Licensed under the Apache License, Version 2.0 (the "License");
53bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * you may not use this file except in compliance with the License.
63bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * You may obtain a copy of the License at
73bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy *
83bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy *      http://www.apache.org/licenses/LICENSE-2.0
93bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy *
103bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * Unless required by applicable law or agreed to in writing, software
113bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * distributed under the License is distributed on an "AS IS" BASIS,
123bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * See the License for the specific language governing permissions and
143bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * limitations under the License.
153bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy */
163bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
173bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#ifndef ANDROID_HWUI_RENDER_BUFFER_H
183bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#define ANDROID_HWUI_RENDER_BUFFER_H
193bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
203bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#include <GLES2/gl2.h>
213bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#include <GLES2/gl2ext.h>
223bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
233bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guynamespace android {
243bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guynamespace uirenderer {
253bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
263bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy/**
273bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * Represents an OpenGL render buffer. Render buffers are attached
283bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy * to layers to perform stencil work.
293bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy */
303bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guystruct RenderBuffer {
313bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
323bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Creates a new render buffer in the specified format and dimensions.
333bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * The format must be one of the formats allowed by glRenderbufferStorage().
343bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
353bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    RenderBuffer(GLenum format, uint32_t width, uint32_t height):
363bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        mFormat(format), mWidth(width), mHeight(height), mAllocated(false) {
373bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
383bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        glGenRenderbuffers(1, &mName);
393bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
403bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
413bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    ~RenderBuffer() {
428d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        if (mName) {
433bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            glDeleteRenderbuffers(1, &mName);
443bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        }
453bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
463bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
473bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
483bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Returns the GL name of this render buffer.
493bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
503bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    GLuint getName() const {
513bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        return mName;
523bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
533bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
543bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
553bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Returns the format of this render buffer.
563bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
573bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    GLenum getFormat() const {
583bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        return mFormat;
593bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
603bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
613bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
623bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Binds this render buffer to the current GL context.
633bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
643bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    void bind() const {
653bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        glBindRenderbuffer(GL_RENDERBUFFER, mName);
663bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
673bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
683bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
693bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Indicates whether this render buffer has allocated its
703bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * storage. See allocate() and resize().
713bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
723bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    bool isAllocated() const {
733bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        return mAllocated;
743bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
753bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
763bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
773bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Allocates this render buffer's storage if needed.
783bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * This method doesn't do anything if isAllocated() returns true.
793bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
803bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    void allocate() {
813bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        if (!mAllocated) {
823bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            glRenderbufferStorage(GL_RENDERBUFFER, mFormat, mWidth, mHeight);
833bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            mAllocated = true;
843bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        }
853bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
863bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
873bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
883bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Resizes this render buffer. If the buffer was previously allocated,
893bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * the storage is re-allocated wit the new specified dimensions. If the
903bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * buffer wasn't previously allocated, the buffer remains unallocated.
913bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
923bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    void resize(uint32_t width, uint32_t height) {
933bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        if (isAllocated() && (width != mWidth || height != mHeight)) {
943bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            glRenderbufferStorage(GL_RENDERBUFFER, mFormat, width, height);
953bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        }
963bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
973bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        mWidth = width;
983bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        mHeight = height;
993bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
1003bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
1013bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
1023bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Returns the width of the render buffer in pixels.
1033bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
1043bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    uint32_t getWidth() const {
1053bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        return mWidth;
1063bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
1073bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
1083bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
1093bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Returns the height of the render buffer in pixels.
1103bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
1113bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    uint32_t getHeight() const {
1123bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        return mHeight;
1133bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
1143bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
1153bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
1163bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Returns the size of this render buffer in bytes.
1173bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
1183bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    uint32_t getSize() const {
1193bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        // Round to the nearest byte
1203bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        return (uint32_t) ((mWidth * mHeight * formatSize(mFormat)) / 8.0f + 0.5f);
1213bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
1223bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
1233bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
1243bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Returns the number of bits per component in the specified format.
1253bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * The format must be one of the formats allowed by glRenderbufferStorage().
1263bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
1273bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    static uint32_t formatSize(GLenum format) {
1283bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        switch (format) {
1293bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            case GL_STENCIL_INDEX8:
1303bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy                return 8;
1313bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            case GL_STENCIL_INDEX1_OES:
1323bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy                return 1;
1333bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            case GL_STENCIL_INDEX4_OES:
1343bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy                return 4;
1353bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            case GL_DEPTH_COMPONENT16:
1363bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            case GL_RGBA4:
1373bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            case GL_RGB565:
1383bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            case GL_RGB5_A1:
1393bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy                return 16;
1403bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        }
1413bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        return 0;
1423bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
1433bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
1443bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
1453bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Indicates whether the specified format represents a stencil buffer.
1463bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
1473bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    static bool isStencilBuffer(GLenum format) {
1483bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        switch (format) {
1493bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            case GL_STENCIL_INDEX8:
1503bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            case GL_STENCIL_INDEX1_OES:
1513bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            case GL_STENCIL_INDEX4_OES:
1523bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy                return true;
1533bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        }
1543bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        return false;
1553bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
1563bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
1578d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    /**
1588d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     * Returns the name of the specified render buffer format.
1598d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     */
1608d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    static const char* formatName(GLenum format) {
1618d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        switch (format) {
1628d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            case GL_STENCIL_INDEX8:
1638d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy                return "STENCIL_8";
1648d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            case GL_STENCIL_INDEX1_OES:
1658d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy                return "STENCIL_1";
1668d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            case GL_STENCIL_INDEX4_OES:
1678d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy                return "STENCIL_4";
1688d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            case GL_DEPTH_COMPONENT16:
1698d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy                return "DEPTH_16";
1708d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            case GL_RGBA4:
1712b44eb75c42e4caa94f0b002f0ea9e134fe7b543Romain Guy                return "RGBA_4444";
1728d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            case GL_RGB565:
1738d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy                return "RGB_565";
1748d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            case GL_RGB5_A1:
1758d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy                return "RGBA_5551";
1768d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        }
1778d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        return "Unknown";
1788d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    }
1798d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1803bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guyprivate:
1813bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    GLenum mFormat;
1823bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
1833bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    uint32_t mWidth;
1843bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    uint32_t mHeight;
1853bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
1863bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    bool mAllocated;
1873bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
1883bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    GLuint mName;
1893bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy}; // struct RenderBuffer
1903bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
1913bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy}; // namespace uirenderer
1923bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy}; // namespace android
1933bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
1943bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#endif // ANDROID_HWUI_RENDER_BUFFER_H
195