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     */
351bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    RenderBuffer(GLenum format, uint32_t width, uint32_t height)
361bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck            : mFormat(format), mWidth(width), mHeight(height), mAllocated(false) {
373bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        glGenRenderbuffers(1, &mName);
383bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
393bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
403bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    ~RenderBuffer() {
418d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        if (mName) {
423bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            glDeleteRenderbuffers(1, &mName);
433bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        }
443bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
453bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
463bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
473bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Returns the GL name of this render buffer.
483bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
491bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    GLuint getName() const { return mName; }
503bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
513bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
523bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Returns the format of this render buffer.
533bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
541bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    GLenum getFormat() const { return mFormat; }
553bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
563bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
573bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Binds this render buffer to the current GL context.
583bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
591bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    void bind() const { glBindRenderbuffer(GL_RENDERBUFFER, mName); }
603bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
613bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
623bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Indicates whether this render buffer has allocated its
633bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * storage. See allocate() and resize().
643bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
651bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    bool isAllocated() const { return mAllocated; }
663bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
673bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
683bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Allocates this render buffer's storage if needed.
693bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * This method doesn't do anything if isAllocated() returns true.
703bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
713bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    void allocate() {
723bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        if (!mAllocated) {
733bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            glRenderbufferStorage(GL_RENDERBUFFER, mFormat, mWidth, mHeight);
743bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            mAllocated = true;
753bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        }
763bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
773bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
783bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
793bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Resizes this render buffer. If the buffer was previously allocated,
803bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * the storage is re-allocated wit the new specified dimensions. If the
813bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * buffer wasn't previously allocated, the buffer remains unallocated.
823bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
833bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    void resize(uint32_t width, uint32_t height) {
843bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        if (isAllocated() && (width != mWidth || height != mHeight)) {
853bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            glRenderbufferStorage(GL_RENDERBUFFER, mFormat, width, height);
863bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        }
873bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
883bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        mWidth = width;
893bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        mHeight = height;
903bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
913bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
923bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
933bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Returns the width of the render buffer in pixels.
943bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
951bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    uint32_t getWidth() const { return mWidth; }
963bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
973bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
983bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Returns the height of the render buffer in pixels.
993bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
1001bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    uint32_t getHeight() const { return mHeight; }
1013bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
1023bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
1033bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Returns the size of this render buffer in bytes.
1043bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
1053bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    uint32_t getSize() const {
1063bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        // Round to the nearest byte
1071bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck        return (uint32_t)((mWidth * mHeight * formatSize(mFormat)) / 8.0f + 0.5f);
1083bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
1093bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
1103bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
1113bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Returns the number of bits per component in the specified format.
1123bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * The format must be one of the formats allowed by glRenderbufferStorage().
1133bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
1143bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    static uint32_t formatSize(GLenum format) {
1153bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        switch (format) {
1163bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            case GL_STENCIL_INDEX8:
1173bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy                return 8;
1183bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            case GL_STENCIL_INDEX1_OES:
1193bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy                return 1;
1203bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            case GL_STENCIL_INDEX4_OES:
1213bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy                return 4;
1223bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            case GL_DEPTH_COMPONENT16:
1233bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            case GL_RGBA4:
1243bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            case GL_RGB565:
1253bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            case GL_RGB5_A1:
1263bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy                return 16;
1273bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        }
1283bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        return 0;
1293bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
1303bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
1313bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    /**
1323bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     * Indicates whether the specified format represents a stencil buffer.
1333bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy     */
1343bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    static bool isStencilBuffer(GLenum format) {
1353bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        switch (format) {
1363bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            case GL_STENCIL_INDEX8:
1373bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            case GL_STENCIL_INDEX1_OES:
1383bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy            case GL_STENCIL_INDEX4_OES:
1393bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy                return true;
1403bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        }
1413bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        return false;
1423bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
1433bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
1448d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    /**
1458d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     * Returns the name of the specified render buffer format.
1468d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy     */
1478d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    static const char* formatName(GLenum format) {
1488d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        switch (format) {
1498d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            case GL_STENCIL_INDEX8:
1508d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy                return "STENCIL_8";
1518d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            case GL_STENCIL_INDEX1_OES:
1528d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy                return "STENCIL_1";
1538d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            case GL_STENCIL_INDEX4_OES:
1548d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy                return "STENCIL_4";
1558d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            case GL_DEPTH_COMPONENT16:
1568d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy                return "DEPTH_16";
1578d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            case GL_RGBA4:
1582b44eb75c42e4caa94f0b002f0ea9e134fe7b543Romain Guy                return "RGBA_4444";
1598d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            case GL_RGB565:
1608d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy                return "RGB_565";
1618d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            case GL_RGB5_A1:
1628d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy                return "RGBA_5551";
1638d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        }
1648d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy        return "Unknown";
1658d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    }
1668d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy
1673bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guyprivate:
1683bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    GLenum mFormat;
1693bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
1703bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    uint32_t mWidth;
1713bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    uint32_t mHeight;
1723bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
1733bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    bool mAllocated;
1743bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
1753bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    GLuint mName;
1761bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck};  // struct RenderBuffer
1773bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
1781bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck};  // namespace uirenderer
1791bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck};  // namespace android
1803bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
1811bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck#endif  // ANDROID_HWUI_RENDER_BUFFER_H
182