diff options
Diffstat (limited to 'libs/hwui/PixelBuffer.h')
| -rw-r--r-- | libs/hwui/PixelBuffer.h | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/libs/hwui/PixelBuffer.h b/libs/hwui/PixelBuffer.h new file mode 100644 index 000000000000..e7e341b90ad3 --- /dev/null +++ b/libs/hwui/PixelBuffer.h @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HWUI_PIXEL_BUFFER_H +#define ANDROID_HWUI_PIXEL_BUFFER_H + +#include <GLES3/gl3.h> + +#include <log/log.h> + +namespace android { +namespace uirenderer { + +/** + * Represents a pixel buffer. A pixel buffer will be backed either by a + * PBO on OpenGL ES 3.0 and higher or by an array of uint8_t on other + * versions. If the buffer is backed by a PBO it will of type + * GL_PIXEL_UNPACK_BUFFER. + * + * To read from or write into a PixelBuffer you must first map the + * buffer using the map(AccessMode) method. This method returns a + * pointer to the beginning of the buffer. + * + * Before the buffer can be used by the GPU, for instance to upload + * a texture, you must first unmap the buffer. To do so, call the + * unmap() method. + * + * Mapping and unmapping a PixelBuffer can have the side effect of + * changing the currently active GL_PIXEL_UNPACK_BUFFER. It is + * therefore recommended to call Caches::unbindPixelbuffer() after + * using a PixelBuffer to upload to a texture. + */ +class PixelBuffer { +public: + enum BufferType { kBufferType_Auto, kBufferType_CPU }; + + enum AccessMode { + kAccessMode_None = 0, + kAccessMode_Read = GL_MAP_READ_BIT, + kAccessMode_Write = GL_MAP_WRITE_BIT, + kAccessMode_ReadWrite = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT + }; + + /** + * Creates a new PixelBuffer object with the specified format and + * dimensions. The buffer is immediately allocated. + * + * The buffer type specifies how the buffer should be allocated. + * By default this method will automatically choose whether to allocate + * a CPU or GPU buffer. + */ + static PixelBuffer* create(GLenum format, uint32_t width, uint32_t height, + BufferType type = kBufferType_Auto); + + virtual ~PixelBuffer() {} + + /** + * Returns the format of this render buffer. + */ + GLenum getFormat() const { return mFormat; } + + /** + * Maps this before with the specified access mode. This method + * returns a pointer to the region of memory where the buffer was + * mapped. + * + * If the buffer is already mapped when this method is invoked, + * this method will return the previously mapped pointer. The + * access mode can only be changed by calling unmap() first. + * + * The specified access mode cannot be kAccessMode_None. + */ + virtual uint8_t* map(AccessMode mode = kAccessMode_ReadWrite) = 0; + + /** + * Returns the current access mode for this buffer. If the buffer + * is not mapped, this method returns kAccessMode_None. + */ + AccessMode getAccessMode() const { return mAccessMode; } + + /** + * Upload the specified rectangle of this pixel buffer as a + * GL_TEXTURE_2D texture. Calling this method will trigger + * an unmap() if necessary. + */ + virtual void upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset) = 0; + + /** + * Upload the specified rectangle of this pixel buffer as a + * GL_TEXTURE_2D texture. Calling this method will trigger + * an unmap() if necessary. + * + * This is a convenience function provided to save callers the + * trouble of computing the offset parameter. + */ + void upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height) { + upload(x, y, width, height, getOffset(x, y)); + } + + /** + * Returns the width of the render buffer in pixels. + */ + uint32_t getWidth() const { return mWidth; } + + /** + * Returns the height of the render buffer in pixels. + */ + uint32_t getHeight() const { return mHeight; } + + /** + * Returns the size of this pixel buffer in bytes. + */ + uint32_t getSize() const { return mWidth * mHeight * formatSize(mFormat); } + + /** + * Returns the offset of a pixel in this pixel buffer, in bytes. + */ + uint32_t getOffset(uint32_t x, uint32_t y) const { + return (y * mWidth + x) * formatSize(mFormat); + } + + /** + * Returns the number of bytes per pixel in the specified format. + * + * Supported formats: + * GL_ALPHA + * GL_RGBA + */ + static uint32_t formatSize(GLenum format) { + switch (format) { + case GL_ALPHA: + return 1; + case GL_RGBA: + return 4; + } + return 0; + } + + /** + * Returns the alpha channel offset in the specified format. + * + * Supported formats: + * GL_ALPHA + * GL_RGBA + */ + static uint32_t formatAlphaOffset(GLenum format) { + switch (format) { + case GL_ALPHA: + return 0; + case GL_RGBA: + return 3; + } + + ALOGE("unsupported format: %d", format); + return 0; + } + +protected: + /** + * Creates a new render buffer in the specified format and dimensions. + * The format must be GL_ALPHA or GL_RGBA. + */ + PixelBuffer(GLenum format, uint32_t width, uint32_t height) + : mFormat(format), mWidth(width), mHeight(height), mAccessMode(kAccessMode_None) {} + + /** + * Unmaps this buffer, if needed. After the buffer is unmapped, + * the pointer previously returned by map() becomes invalid and + * should not be used. + */ + virtual void unmap() = 0; + + GLenum mFormat; + + uint32_t mWidth; + uint32_t mHeight; + + AccessMode mAccessMode; + +}; // class PixelBuffer + +}; // namespace uirenderer +}; // namespace android + +#endif // ANDROID_HWUI_PIXEL_BUFFER_H |