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 34cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyclass 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) 5151d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik , mBuffer(new uint8_t[width * height * formatSize(format)]) { 52cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 53cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 54cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyuint8_t* CpuPixelBuffer::map(AccessMode mode) { 55cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy if (mAccessMode == kAccessMode_None) { 56cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mAccessMode = mode; 57cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy } 5851d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik return mBuffer.get(); 59cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 60cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 61cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyvoid CpuPixelBuffer::unmap() { 62cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mAccessMode = kAccessMode_None; 63cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 64cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 65cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyvoid CpuPixelBuffer::upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset) { 66cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, 6751d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik mFormat, GL_UNSIGNED_BYTE, &mBuffer[offset]); 68cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 69cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 70cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy/////////////////////////////////////////////////////////////////////////////// 71cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy// GPU pixel buffer 72cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy/////////////////////////////////////////////////////////////////////////////// 73cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 74cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyclass GpuPixelBuffer: public PixelBuffer { 75cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guypublic: 76cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy GpuPixelBuffer(GLenum format, uint32_t width, uint32_t height); 77cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy ~GpuPixelBuffer(); 78cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 79d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik uint8_t* map(AccessMode mode = kAccessMode_ReadWrite) override; 80cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 81d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik void upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset) override; 82cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 83f3ad324a8d3f5b5530bd1945f461faf4b0adec8cJohn Reckprotected: 84f3ad324a8d3f5b5530bd1945f461faf4b0adec8cJohn Reck void unmap() override; 85f3ad324a8d3f5b5530bd1945f461faf4b0adec8cJohn Reck 86cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyprivate: 87cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy GLuint mBuffer; 88cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy uint8_t* mMappedPointer; 89cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy Caches& mCaches; 90cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}; 91cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 9296a5c4c7bab6718524de7253da8309143ab48befChris CraikGpuPixelBuffer::GpuPixelBuffer(GLenum format, 9396a5c4c7bab6718524de7253da8309143ab48befChris Craik uint32_t width, uint32_t height) 94d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik : PixelBuffer(format, width, height) 95d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik , mMappedPointer(nullptr) 9696a5c4c7bab6718524de7253da8309143ab48befChris Craik , mCaches(Caches::getInstance()){ 97cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy glGenBuffers(1, &mBuffer); 9896a5c4c7bab6718524de7253da8309143ab48befChris Craik 9944eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches.pixelBufferState().bind(mBuffer); 100d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik glBufferData(GL_PIXEL_UNPACK_BUFFER, getSize(), nullptr, GL_DYNAMIC_DRAW); 10144eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches.pixelBufferState().unbind(); 102cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 103cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 104cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain GuyGpuPixelBuffer::~GpuPixelBuffer() { 105cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy glDeleteBuffers(1, &mBuffer); 106cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 107cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 108cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyuint8_t* GpuPixelBuffer::map(AccessMode mode) { 109cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy if (mAccessMode == kAccessMode_None) { 11044eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches.pixelBufferState().bind(mBuffer); 111cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mMappedPointer = (uint8_t*) glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, getSize(), mode); 1122de7771740ee08fcaff638ec6b2e460bb72fff04John Reck if (CC_UNLIKELY(!mMappedPointer)) { 1132de7771740ee08fcaff638ec6b2e460bb72fff04John Reck GLUtils::dumpGLErrors(); 1142de7771740ee08fcaff638ec6b2e460bb72fff04John Reck LOG_ALWAYS_FATAL("Failed to map PBO"); 1159e6f3ac109b5cd7736122d1bdf83ed38b9d739c6Romain Guy } 116cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mAccessMode = mode; 117f3ad324a8d3f5b5530bd1945f461faf4b0adec8cJohn Reck mCaches.pixelBufferState().unbind(); 118cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy } 119cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 120cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy return mMappedPointer; 121cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 122cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 123cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyvoid GpuPixelBuffer::unmap() { 124cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy if (mAccessMode != kAccessMode_None) { 125cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy if (mMappedPointer) { 12644eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches.pixelBufferState().bind(mBuffer); 12703c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy GLboolean status = glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); 12803c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy if (status == GL_FALSE) { 12903c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy ALOGE("Corrupted GPU pixel buffer"); 13003c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy } 131cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy } 132cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mAccessMode = kAccessMode_None; 133d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik mMappedPointer = nullptr; 134cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy } 135cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 136cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 137cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyvoid GpuPixelBuffer::upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset) { 138cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy // If the buffer is not mapped, unmap() will not bind it 13944eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches.pixelBufferState().bind(mBuffer); 140cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy unmap(); 141cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, mFormat, 14273fc558e44be259c0833c8c8074ad2333bcb378dKévin PETIT GL_UNSIGNED_BYTE, reinterpret_cast<void*>(offset)); 143f3ad324a8d3f5b5530bd1945f461faf4b0adec8cJohn Reck mCaches.pixelBufferState().unbind(); 144cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 145cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 146cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy/////////////////////////////////////////////////////////////////////////////// 147cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy// Factory 148cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy/////////////////////////////////////////////////////////////////////////////// 149cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 15096a5c4c7bab6718524de7253da8309143ab48befChris CraikPixelBuffer* PixelBuffer::create(GLenum format, 15196a5c4c7bab6718524de7253da8309143ab48befChris Craik uint32_t width, uint32_t height, BufferType type) { 152f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy if (type == kBufferType_Auto && Caches::getInstance().gpuPixelBuffersEnabled) { 153f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy return new GpuPixelBuffer(format, width, height); 154cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy } 155cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy return new CpuPixelBuffer(format, width, height); 156cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 157cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 158cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}; // namespace uirenderer 159cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}; // namespace android 160