PixelBuffer.cpp revision f9f0016b1ff816eb2c7561eed482c056189005f8
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" 22cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy#include "Extensions.h" 23cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy#include "PixelBuffer.h" 24cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy#include "Properties.h" 25cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 26cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guynamespace android { 27cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guynamespace uirenderer { 28cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 29cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy/////////////////////////////////////////////////////////////////////////////// 30cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy// CPU pixel buffer 31cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy/////////////////////////////////////////////////////////////////////////////// 32cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 33cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyclass CpuPixelBuffer: public PixelBuffer { 34cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guypublic: 35cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy CpuPixelBuffer(GLenum format, uint32_t width, uint32_t height); 36cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy ~CpuPixelBuffer(); 37cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 38cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy uint8_t* map(AccessMode mode = kAccessMode_ReadWrite); 39cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy void unmap(); 40cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 41cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy uint8_t* getMappedPointer() const; 42cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 43cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy void upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset); 44cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 45cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyprivate: 46cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy uint8_t* mBuffer; 47cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}; 48cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 49cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain GuyCpuPixelBuffer::CpuPixelBuffer(GLenum format, uint32_t width, uint32_t height): 50cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy PixelBuffer(format, width, height) { 51cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mBuffer = new uint8_t[width * height * formatSize(format)]; 52cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 53cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 54cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain GuyCpuPixelBuffer::~CpuPixelBuffer() { 55cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy delete[] mBuffer; 56cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 57cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 58cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyuint8_t* CpuPixelBuffer::map(AccessMode mode) { 59cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy if (mAccessMode == kAccessMode_None) { 60cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mAccessMode = mode; 61cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy } 62cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy return mBuffer; 63cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 64cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 65cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyvoid CpuPixelBuffer::unmap() { 66cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mAccessMode = kAccessMode_None; 67cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 68cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 69cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyuint8_t* CpuPixelBuffer::getMappedPointer() const { 70cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy return mAccessMode == kAccessMode_None ? NULL : mBuffer; 71cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 72cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 73cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyvoid CpuPixelBuffer::upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset) { 74cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, 75cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mFormat, GL_UNSIGNED_BYTE, mBuffer + offset); 76cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 77cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 78cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy/////////////////////////////////////////////////////////////////////////////// 79cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy// GPU pixel buffer 80cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy/////////////////////////////////////////////////////////////////////////////// 81cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 82cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyclass GpuPixelBuffer: public PixelBuffer { 83cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guypublic: 84cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy GpuPixelBuffer(GLenum format, uint32_t width, uint32_t height); 85cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy ~GpuPixelBuffer(); 86cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 87cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy uint8_t* map(AccessMode mode = kAccessMode_ReadWrite); 88cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy void unmap(); 89cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 90cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy uint8_t* getMappedPointer() const; 91cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 92cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy void upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset); 93cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 94cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyprivate: 95cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy GLuint mBuffer; 96cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy uint8_t* mMappedPointer; 97cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy Caches& mCaches; 98cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}; 99cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 100cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain GuyGpuPixelBuffer::GpuPixelBuffer(GLenum format, uint32_t width, uint32_t height): 101cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy PixelBuffer(format, width, height), mMappedPointer(0), mCaches(Caches::getInstance()) { 102cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy glGenBuffers(1, &mBuffer); 103cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mCaches.bindPixelBuffer(mBuffer); 104cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy glBufferData(GL_PIXEL_UNPACK_BUFFER, getSize(), NULL, GL_DYNAMIC_DRAW); 105cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mCaches.unbindPixelBuffer(); 106cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 107cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 108cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain GuyGpuPixelBuffer::~GpuPixelBuffer() { 109cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy glDeleteBuffers(1, &mBuffer); 110cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 111cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 112cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyuint8_t* GpuPixelBuffer::map(AccessMode mode) { 113cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy if (mAccessMode == kAccessMode_None) { 114cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mCaches.bindPixelBuffer(mBuffer); 115cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mMappedPointer = (uint8_t*) glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, getSize(), mode); 116cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mAccessMode = mode; 117cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy } 118cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 119cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy return mMappedPointer; 120cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 121cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 122cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyvoid GpuPixelBuffer::unmap() { 123cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy if (mAccessMode != kAccessMode_None) { 124cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy if (mMappedPointer) { 125cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mCaches.bindPixelBuffer(mBuffer); 126cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); 127cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy } 128cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mAccessMode = kAccessMode_None; 129cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mMappedPointer = NULL; 130cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy } 131cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 132cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 133cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyuint8_t* GpuPixelBuffer::getMappedPointer() const { 134cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy return mMappedPointer; 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 139cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy mCaches.bindPixelBuffer(mBuffer); 140cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy unmap(); 141cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, mFormat, 142cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy GL_UNSIGNED_BYTE, (void*) offset); 143cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 144cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 145cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy/////////////////////////////////////////////////////////////////////////////// 146cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy// Factory 147cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy/////////////////////////////////////////////////////////////////////////////// 148cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 149cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain GuyPixelBuffer* PixelBuffer::create(GLenum format, uint32_t width, uint32_t height, BufferType type) { 150f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy if (type == kBufferType_Auto && Caches::getInstance().gpuPixelBuffersEnabled) { 151f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy return new GpuPixelBuffer(format, width, height); 152cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy } 153cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy return new CpuPixelBuffer(format, width, height); 154cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy} 155cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 156cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}; // namespace uirenderer 157cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}; // namespace android 158