/* * Copyright (C) 2011 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 _LIBRENDER_COLORBUFFER_H #define _LIBRENDER_COLORBUFFER_H #include #include #include #include class TextureDraw; class TextureResize; // A class used to model a guest color buffer, and used to implement several // related things: // // - Every gralloc native buffer with HW read or write requirements will // allocate a host ColorBuffer instance. When gralloc_lock() is called, // the guest will use ColorBuffer::readPixels() to read the current content // of the buffer. When gralloc_unlock() is later called, it will call // ColorBuffer::subUpdate() to send the updated pixels. // // - Every guest window EGLSurface is implemented by a host PBuffer // (see WindowSurface.h) that can have a ColorBuffer instance attached to // it (through WindowSurface::attachColorBuffer()). When such an attachment // exists, WindowSurface::flushColorBuffer() will copy the PBuffer's // pixel data into the ColorBuffer. The latter can then be displayed // in the client's UI sub-window with ColorBuffer::post(). // // - Guest EGLImages are implemented as native gralloc buffers too. // The guest glEGLImageTargetTexture2DOES() implementations will end up // calling ColorBuffer::bindToTexture() to bind the current context's // GL_TEXTURE_2D to the buffer. Similarly, the guest versions of // glEGLImageTargetRenderbufferStorageOES() will end up calling // ColorBuffer::bindToRenderbuffer(). // // This forces the implementation to use a host EGLImage to implement each // ColorBuffer. // // As an additional twist. class ColorBuffer { public: // Helper interface class used during ColorBuffer operations. This is // introduced to remove coupling from the FrameBuffer class implementation. class Helper { public: Helper() {} virtual ~Helper() {} virtual bool setupContext() = 0; virtual void teardownContext() = 0; virtual TextureDraw* getTextureDraw() const = 0; }; // Create a new ColorBuffer instance. // |p_display| is the host EGLDisplay handle. // |p_width| and |p_height| are the buffer's dimensions in pixels. // |p_internalFormat| is the internal pixel format to use, valid values // are: GL_RGB, GL_RGB565, GL_RGBA, GL_RGB5_A1_OES and GL_RGBA4_OES. // Implementation is free to use something else though. // |has_eglimage_texture_2d| should be true iff the display supports // the EGL_KHR_gl_texture_2D_image extension. // Returns NULL on failure. static ColorBuffer* create(EGLDisplay p_display, int p_width, int p_height, GLenum p_internalFormat, bool has_eglimage_texture_2d, Helper* helper); // Destructor. ~ColorBuffer(); // Return ColorBuffer width and height in pixels GLuint getWidth() const { return m_width; } GLuint getHeight() const { return m_height; } // Read the ColorBuffer instance's pixel values into host memory. void readPixels(int x, int y, int width, int height, GLenum p_format, GLenum p_type, void* pixels); // Update the ColorBuffer instance's pixel values from host memory. void subUpdate(int x, int y, int width, int height, GLenum p_format, GLenum p_type, void* pixels); // Bind the current context's EGL_TEXTURE_2D texture to this ColorBuffer's // EGLImage. This is intended to implement glEGLImageTargetTexture2DOES() // for all GLES versions. bool bindToTexture(); // Bind the current context's EGL_RENDERBUFFER_OES render buffer to this // ColorBuffer's EGLImage. This is intended to implement // glEGLImageTargetRenderbufferStorageOES() for all GLES versions. bool bindToRenderbuffer(); // Copy the content of the current context's read surface to this // ColorBuffer. This is used from WindowSurface::flushColorBuffer(). // Return true on success, false on failure (e.g. no current context). bool blitFromCurrentReadBuffer(); // Read the content of the whole ColorBuffer as 32-bit RGBA pixels. // |img| must be a buffer large enough (i.e. width * height * 4). void readback(unsigned char* img); void bind(); private: ColorBuffer(); // no default constructor. explicit ColorBuffer(EGLDisplay display, Helper* helper); private: GLuint m_tex; GLuint m_blitTex; EGLImageKHR m_eglImage; EGLImageKHR m_blitEGLImage; GLuint m_width; GLuint m_height; GLuint m_fbo; GLenum m_internalFormat; EGLDisplay m_display; Helper* m_helper; TextureResize* m_resizer; }; typedef std::shared_ptr ColorBufferPtr; #endif