1cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy/*
2cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy * Copyright (C) 2013 The Android Open Source Project
3cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy *
4cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
5cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy * you may not use this file except in compliance with the License.
6cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy * You may obtain a copy of the License at
7cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy *
8cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
9cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy *
10cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy * Unless required by applicable law or agreed to in writing, software
11cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
12cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy * See the License for the specific language governing permissions and
14cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy * limitations under the License.
15cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy */
16cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
17cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy#define LOG_TAG "OpenGLRenderer"
18cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
1996a5c4c7bab6718524de7253da8309143ab48befChris Craik#include "PixelBuffer.h"
20cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
219e6f3ac109b5cd7736122d1bdf83ed38b9d739c6Romain Guy#include "Debug.h"
22cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy#include "Extensions.h"
23cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy#include "Properties.h"
2496a5c4c7bab6718524de7253da8309143ab48befChris Craik#include "renderstate/RenderState.h"
2596a5c4c7bab6718524de7253da8309143ab48befChris Craik
2696a5c4c7bab6718524de7253da8309143ab48befChris Craik#include <utils/Log.h>
27cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
28cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guynamespace android {
29cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guynamespace uirenderer {
30cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
31cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy///////////////////////////////////////////////////////////////////////////////
32cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy// CPU pixel buffer
33cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy///////////////////////////////////////////////////////////////////////////////
34cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
35cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyclass CpuPixelBuffer: public PixelBuffer {
36cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guypublic:
37cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    CpuPixelBuffer(GLenum format, uint32_t width, uint32_t height);
38cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
39d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    uint8_t* map(AccessMode mode = kAccessMode_ReadWrite) override;
40d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    void unmap() override;
41cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
42d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    uint8_t* getMappedPointer() const override;
43cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
44d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    void upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset) override;
45cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
46cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyprivate:
4751d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik    std::unique_ptr<uint8_t[]> mBuffer;
48cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy};
49cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
5051d6a3db97bdd5315f1a17a4b447d10a92217b98Chris CraikCpuPixelBuffer::CpuPixelBuffer(GLenum format, uint32_t width, uint32_t height)
5151d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik        : PixelBuffer(format, width, height)
5251d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik        , mBuffer(new uint8_t[width * height * formatSize(format)]) {
53cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}
54cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
55cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyuint8_t* CpuPixelBuffer::map(AccessMode mode) {
56cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    if (mAccessMode == kAccessMode_None) {
57cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy        mAccessMode = mode;
58cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    }
5951d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik    return mBuffer.get();
60cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}
61cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
62cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyvoid CpuPixelBuffer::unmap() {
63cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    mAccessMode = kAccessMode_None;
64cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}
65cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
66cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyuint8_t* CpuPixelBuffer::getMappedPointer() const {
6751d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik    return mAccessMode == kAccessMode_None ? nullptr : mBuffer.get();
68cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}
69cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
70cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyvoid CpuPixelBuffer::upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset) {
71cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height,
7251d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik            mFormat, GL_UNSIGNED_BYTE, &mBuffer[offset]);
73cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}
74cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
75cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy///////////////////////////////////////////////////////////////////////////////
76cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy// GPU pixel buffer
77cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy///////////////////////////////////////////////////////////////////////////////
78cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
79cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyclass GpuPixelBuffer: public PixelBuffer {
80cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guypublic:
81cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    GpuPixelBuffer(GLenum format, uint32_t width, uint32_t height);
82cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    ~GpuPixelBuffer();
83cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
84d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    uint8_t* map(AccessMode mode = kAccessMode_ReadWrite) override;
85d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    void unmap() override;
86cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
87d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    uint8_t* getMappedPointer() const override;
88cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
89d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    void upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset) override;
90cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
91cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyprivate:
92cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    GLuint mBuffer;
93cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    uint8_t* mMappedPointer;
94cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    Caches& mCaches;
95cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy};
96cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
9796a5c4c7bab6718524de7253da8309143ab48befChris CraikGpuPixelBuffer::GpuPixelBuffer(GLenum format,
9896a5c4c7bab6718524de7253da8309143ab48befChris Craik        uint32_t width, uint32_t height)
99d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik        : PixelBuffer(format, width, height)
100d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik        , mMappedPointer(nullptr)
10196a5c4c7bab6718524de7253da8309143ab48befChris Craik        , mCaches(Caches::getInstance()){
102cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    glGenBuffers(1, &mBuffer);
10396a5c4c7bab6718524de7253da8309143ab48befChris Craik
10444eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik    mCaches.pixelBufferState().bind(mBuffer);
105d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    glBufferData(GL_PIXEL_UNPACK_BUFFER, getSize(), nullptr, GL_DYNAMIC_DRAW);
10644eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik    mCaches.pixelBufferState().unbind();
107cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}
108cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
109cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain GuyGpuPixelBuffer::~GpuPixelBuffer() {
110cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    glDeleteBuffers(1, &mBuffer);
111cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}
112cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
113cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyuint8_t* GpuPixelBuffer::map(AccessMode mode) {
114cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    if (mAccessMode == kAccessMode_None) {
11544eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik        mCaches.pixelBufferState().bind(mBuffer);
116cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy        mMappedPointer = (uint8_t*) glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, getSize(), mode);
1179e6f3ac109b5cd7736122d1bdf83ed38b9d739c6Romain Guy#if DEBUG_OPENGL
1189e6f3ac109b5cd7736122d1bdf83ed38b9d739c6Romain Guy        if (!mMappedPointer) {
1199e6f3ac109b5cd7736122d1bdf83ed38b9d739c6Romain Guy            GLenum status = GL_NO_ERROR;
1209e6f3ac109b5cd7736122d1bdf83ed38b9d739c6Romain Guy            while ((status = glGetError()) != GL_NO_ERROR) {
1219e6f3ac109b5cd7736122d1bdf83ed38b9d739c6Romain Guy                ALOGE("Could not map GPU pixel buffer: 0x%x", status);
1229e6f3ac109b5cd7736122d1bdf83ed38b9d739c6Romain Guy            }
1239e6f3ac109b5cd7736122d1bdf83ed38b9d739c6Romain Guy        }
1249e6f3ac109b5cd7736122d1bdf83ed38b9d739c6Romain Guy#endif
125cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy        mAccessMode = mode;
126cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    }
127cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
128cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    return mMappedPointer;
129cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}
130cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
131cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyvoid GpuPixelBuffer::unmap() {
132cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    if (mAccessMode != kAccessMode_None) {
133cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy        if (mMappedPointer) {
13444eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik            mCaches.pixelBufferState().bind(mBuffer);
13503c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy            GLboolean status = glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
13603c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy            if (status == GL_FALSE) {
13703c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy                ALOGE("Corrupted GPU pixel buffer");
13803c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy            }
139cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy        }
140cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy        mAccessMode = kAccessMode_None;
141d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik        mMappedPointer = nullptr;
142cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    }
143cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}
144cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
145cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyuint8_t* GpuPixelBuffer::getMappedPointer() const {
146cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    return mMappedPointer;
147cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}
148cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
149cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyvoid GpuPixelBuffer::upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset) {
150cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    // If the buffer is not mapped, unmap() will not bind it
15144eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik    mCaches.pixelBufferState().bind(mBuffer);
152cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    unmap();
153cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, mFormat,
15473fc558e44be259c0833c8c8074ad2333bcb378dKévin PETIT            GL_UNSIGNED_BYTE, reinterpret_cast<void*>(offset));
155cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}
156cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
157cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy///////////////////////////////////////////////////////////////////////////////
158cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy// Factory
159cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy///////////////////////////////////////////////////////////////////////////////
160cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
16196a5c4c7bab6718524de7253da8309143ab48befChris CraikPixelBuffer* PixelBuffer::create(GLenum format,
16296a5c4c7bab6718524de7253da8309143ab48befChris Craik        uint32_t width, uint32_t height, BufferType type) {
163f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy    if (type == kBufferType_Auto && Caches::getInstance().gpuPixelBuffersEnabled) {
164f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy        return new GpuPixelBuffer(format, width, height);
165cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    }
166cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    return new CpuPixelBuffer(format, width, height);
167cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}
168cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
169cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}; // namespace uirenderer
170cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}; // namespace android
171