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 19cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy#include <utils/Log.h> 20cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 21cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy#include "Caches.h" 229e6f3ac109b5cd7736122d1bdf83ed38b9d739c6Romain Guy#include "Debug.h" 23cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy#include "Extensions.h" 24cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy#include "PixelBuffer.h" 25cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy#include "Properties.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 ~CpuPixelBuffer(); 38cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 39cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy uint8_t* map(AccessMode mode = kAccessMode_ReadWrite); 40cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy void unmap(); 41cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 42cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy uint8_t* getMappedPointer() const; 43cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 44cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy void upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset); 45cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 46cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyprivate: 47cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy uint8_t* mBuffer; 48cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}; 49cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 50cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain GuyCpuPixelBuffer::CpuPixelBuffer(GLenum format, uint32_t width, uint32_t height): 51cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy PixelBuffer(format, width, height) { 52cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mBuffer = new uint8_t[width * height * formatSize(format)]; 53cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 54cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 55cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain GuyCpuPixelBuffer::~CpuPixelBuffer() { 56cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy delete[] mBuffer; 57cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 58cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 59cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyuint8_t* CpuPixelBuffer::map(AccessMode mode) { 60cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy if (mAccessMode == kAccessMode_None) { 61cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mAccessMode = mode; 62cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy } 63cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy return mBuffer; 64cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 65cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 66cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyvoid CpuPixelBuffer::unmap() { 67cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mAccessMode = kAccessMode_None; 68cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 69cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 70cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyuint8_t* CpuPixelBuffer::getMappedPointer() const { 71cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy return mAccessMode == kAccessMode_None ? NULL : mBuffer; 72cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 73cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 74cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyvoid CpuPixelBuffer::upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset) { 75cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, 76cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mFormat, GL_UNSIGNED_BYTE, mBuffer + offset); 77cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 78cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 79cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy/////////////////////////////////////////////////////////////////////////////// 80cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy// GPU pixel buffer 81cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy/////////////////////////////////////////////////////////////////////////////// 82cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 83cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyclass GpuPixelBuffer: public PixelBuffer { 84cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guypublic: 85cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy GpuPixelBuffer(GLenum format, uint32_t width, uint32_t height); 86cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy ~GpuPixelBuffer(); 87cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 88cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy uint8_t* map(AccessMode mode = kAccessMode_ReadWrite); 89cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy void unmap(); 90cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 91cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy uint8_t* getMappedPointer() const; 92cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 93cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy void upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset); 94cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 95cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyprivate: 96cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy GLuint mBuffer; 97cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy uint8_t* mMappedPointer; 98cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy Caches& mCaches; 99cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}; 100cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 101cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain GuyGpuPixelBuffer::GpuPixelBuffer(GLenum format, uint32_t width, uint32_t height): 102cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy PixelBuffer(format, width, height), mMappedPointer(0), mCaches(Caches::getInstance()) { 103cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy glGenBuffers(1, &mBuffer); 104cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mCaches.bindPixelBuffer(mBuffer); 105cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy glBufferData(GL_PIXEL_UNPACK_BUFFER, getSize(), NULL, GL_DYNAMIC_DRAW); 106cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mCaches.unbindPixelBuffer(); 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) { 115cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mCaches.bindPixelBuffer(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) { 134cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mCaches.bindPixelBuffer(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; 141cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mMappedPointer = NULL; 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 151cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mCaches.bindPixelBuffer(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 161cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain GuyPixelBuffer* PixelBuffer::create(GLenum format, uint32_t width, uint32_t height, BufferType type) { 162f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy if (type == kBufferType_Auto && Caches::getInstance().gpuPixelBuffersEnabled) { 163f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy return new GpuPixelBuffer(format, width, height); 164cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy } 165cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy return new CpuPixelBuffer(format, width, height); 166cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 167cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 168cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}; // namespace uirenderer 169cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}; // namespace android 170