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 1796a5c4c7bab6718524de7253da8309143ab48befChris Craik#include "PixelBuffer.h" 18cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 199e6f3ac109b5cd7736122d1bdf83ed38b9d739c6Romain Guy#include "Debug.h" 20cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy#include "Extensions.h" 21cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy#include "Properties.h" 2296a5c4c7bab6718524de7253da8309143ab48befChris Craik#include "renderstate/RenderState.h" 232de7771740ee08fcaff638ec6b2e460bb72fff04John Reck#include "utils/GLUtils.h" 2496a5c4c7bab6718524de7253da8309143ab48befChris Craik 2596a5c4c7bab6718524de7253da8309143ab48befChris Craik#include <utils/Log.h> 26cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 27cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guynamespace android { 28cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guynamespace uirenderer { 29cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 30cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy/////////////////////////////////////////////////////////////////////////////// 31cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy// CPU pixel buffer 32cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy/////////////////////////////////////////////////////////////////////////////// 33cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 341bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reckclass CpuPixelBuffer : public PixelBuffer { 35cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guypublic: 36cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy CpuPixelBuffer(GLenum format, uint32_t width, uint32_t height); 37cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 38d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik uint8_t* map(AccessMode mode = kAccessMode_ReadWrite) override; 39cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 40d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik void upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset) override; 41cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 42f3ad324a8d3f5b5530bd1945f461faf4b0adec8cJohn Reckprotected: 43f3ad324a8d3f5b5530bd1945f461faf4b0adec8cJohn Reck void unmap() override; 44f3ad324a8d3f5b5530bd1945f461faf4b0adec8cJohn Reck 45cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyprivate: 4651d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik std::unique_ptr<uint8_t[]> mBuffer; 47cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}; 48cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 4951d6a3db97bdd5315f1a17a4b447d10a92217b98Chris CraikCpuPixelBuffer::CpuPixelBuffer(GLenum format, uint32_t width, uint32_t height) 5051d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik : PixelBuffer(format, width, height) 511bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck , mBuffer(new uint8_t[width * height * formatSize(format)]) {} 52cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 53cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyuint8_t* CpuPixelBuffer::map(AccessMode mode) { 54cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy if (mAccessMode == kAccessMode_None) { 55cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mAccessMode = mode; 56cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy } 5751d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik return mBuffer.get(); 58cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 59cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 60cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyvoid CpuPixelBuffer::unmap() { 61cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mAccessMode = kAccessMode_None; 62cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 63cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 64cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyvoid CpuPixelBuffer::upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset) { 651bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, mFormat, GL_UNSIGNED_BYTE, 661bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck &mBuffer[offset]); 67cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 68cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 69cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy/////////////////////////////////////////////////////////////////////////////// 70cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy// GPU pixel buffer 71cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy/////////////////////////////////////////////////////////////////////////////// 72cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 731bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reckclass GpuPixelBuffer : public PixelBuffer { 74cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guypublic: 75cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy GpuPixelBuffer(GLenum format, uint32_t width, uint32_t height); 76cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy ~GpuPixelBuffer(); 77cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 78d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik uint8_t* map(AccessMode mode = kAccessMode_ReadWrite) override; 79cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 80d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik void upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset) override; 81cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 82f3ad324a8d3f5b5530bd1945f461faf4b0adec8cJohn Reckprotected: 83f3ad324a8d3f5b5530bd1945f461faf4b0adec8cJohn Reck void unmap() override; 84f3ad324a8d3f5b5530bd1945f461faf4b0adec8cJohn Reck 85cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyprivate: 86cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy GLuint mBuffer; 87cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy uint8_t* mMappedPointer; 88cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy Caches& mCaches; 89cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}; 90cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 911bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John ReckGpuPixelBuffer::GpuPixelBuffer(GLenum format, uint32_t width, uint32_t height) 92d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik : PixelBuffer(format, width, height) 93d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik , mMappedPointer(nullptr) 941bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck , mCaches(Caches::getInstance()) { 95cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy glGenBuffers(1, &mBuffer); 9696a5c4c7bab6718524de7253da8309143ab48befChris Craik 9744eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches.pixelBufferState().bind(mBuffer); 98d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik glBufferData(GL_PIXEL_UNPACK_BUFFER, getSize(), nullptr, GL_DYNAMIC_DRAW); 9944eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches.pixelBufferState().unbind(); 100cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 101cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 102cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain GuyGpuPixelBuffer::~GpuPixelBuffer() { 103cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy glDeleteBuffers(1, &mBuffer); 104cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 105cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 106cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyuint8_t* GpuPixelBuffer::map(AccessMode mode) { 107cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy if (mAccessMode == kAccessMode_None) { 10844eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches.pixelBufferState().bind(mBuffer); 1091bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck mMappedPointer = (uint8_t*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, getSize(), mode); 1102de7771740ee08fcaff638ec6b2e460bb72fff04John Reck if (CC_UNLIKELY(!mMappedPointer)) { 1112de7771740ee08fcaff638ec6b2e460bb72fff04John Reck GLUtils::dumpGLErrors(); 1122de7771740ee08fcaff638ec6b2e460bb72fff04John Reck LOG_ALWAYS_FATAL("Failed to map PBO"); 1139e6f3ac109b5cd7736122d1bdf83ed38b9d739c6Romain Guy } 114cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mAccessMode = mode; 115f3ad324a8d3f5b5530bd1945f461faf4b0adec8cJohn Reck mCaches.pixelBufferState().unbind(); 116cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy } 117cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 118cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy return mMappedPointer; 119cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 120cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 121cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyvoid GpuPixelBuffer::unmap() { 122cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy if (mAccessMode != kAccessMode_None) { 123cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy if (mMappedPointer) { 12444eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches.pixelBufferState().bind(mBuffer); 12503c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy GLboolean status = glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); 12603c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy if (status == GL_FALSE) { 12703c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy ALOGE("Corrupted GPU pixel buffer"); 12803c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy } 129cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy } 130cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mAccessMode = kAccessMode_None; 131d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik mMappedPointer = nullptr; 132cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy } 133cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 134cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 135cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyvoid GpuPixelBuffer::upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset) { 136cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy // If the buffer is not mapped, unmap() will not bind it 13744eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches.pixelBufferState().bind(mBuffer); 138cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy unmap(); 1391bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, mFormat, GL_UNSIGNED_BYTE, 1401bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck reinterpret_cast<void*>(offset)); 141f3ad324a8d3f5b5530bd1945f461faf4b0adec8cJohn Reck mCaches.pixelBufferState().unbind(); 142cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 143cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 144cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy/////////////////////////////////////////////////////////////////////////////// 145cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy// Factory 146cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy/////////////////////////////////////////////////////////////////////////////// 147cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 1481bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John ReckPixelBuffer* PixelBuffer::create(GLenum format, uint32_t width, uint32_t height, BufferType type) { 149f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy if (type == kBufferType_Auto && Caches::getInstance().gpuPixelBuffersEnabled) { 150f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy return new GpuPixelBuffer(format, width, height); 151cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy } 152cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy return new CpuPixelBuffer(format, width, height); 153cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 154cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 1551bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck}; // namespace uirenderer 1561bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck}; // namespace android 157