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