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