| /* |
| * 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> |
| |
| 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; |
| |
| /** |
| * Unmaps this buffer, if needed. After the buffer is unmapped, |
| * the pointer previously returned by map() becomes invalid and |
| * should not be used. After calling this method, getMappedPointer() |
| * will always return NULL. |
| */ |
| virtual void unmap() = 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; |
| } |
| |
| /** |
| * Returns the currently mapped pointer. Returns NULL if the buffer |
| * is not mapped. |
| */ |
| virtual uint8_t* getMappedPointer() const = 0; |
| |
| /** |
| * 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) { |
| } |
| |
| GLenum mFormat; |
| |
| uint32_t mWidth; |
| uint32_t mHeight; |
| |
| AccessMode mAccessMode; |
| |
| }; // class PixelBuffer |
| |
| }; // namespace uirenderer |
| }; // namespace android |
| |
| #endif // ANDROID_HWUI_PIXEL_BUFFER_H |