1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <GLES2/gl2.h> 20 #include <GLES2/gl2ext.h> 21 22 #include "FrameworkFormats.h" 23 24 #include <stdint.h> 25 #include <cstring> 26 #include <vector> 27 28 namespace gfxstream { 29 namespace gl { 30 31 enum class YUVPlane { 32 Y = 0, 33 U = 1, 34 V = 2, 35 UV = 3, 36 }; 37 38 // The purpose of YUVConverter is to use 39 // OpenGL shaders to convert YUV images to RGB 40 // images that can be displayed on screen. 41 // Doing this on the GPU can be much faster than 42 // on the CPU. 43 44 // Usage: 45 // 0. Have a current OpenGL context working. 46 // 1. Constructing the YUVConverter object will allocate 47 // OpenGL resources needed to convert, given the desired 48 // |width| and |height| of the buffer. 49 // 2. To convert a given YUV buffer of |pixels|, call 50 // the drawConvert method (with x, y, width, and height 51 // arguments depicting the region to convert). 52 // The RGB version of the YUV buffer will be drawn 53 // to the current framebuffer. To retrieve 54 // the result, if the user of the result is an OpenGL texture, 55 // it suffices to have that texture be the color attachment 56 // of the framebuffer object. Or, if you want the results 57 // on the CPU, call glReadPixels() after the call to drawConvert(). 58 class YUVConverter { 59 public: 60 // call ctor when creating a gralloc buffer 61 // with YUV format 62 YUVConverter(int width, int height, FrameworkFormat format); 63 // destroy when ColorBuffer is destroyed 64 ~YUVConverter(); 65 // call when gralloc_unlock updates 66 // the host color buffer 67 // (rcUpdateColorBuffer) 68 void drawConvert(int x, int y, int width, int height, const char* pixels); 69 void drawConvertFromFormat(FrameworkFormat format, int x, int y, int width, int height, 70 const char* pixels); 71 72 uint32_t getDataSize(); 73 // read YUV data into pixels, exactly pixels_size bytes; 74 // if size mismatches, will read nothing. 75 void readPixels(uint8_t* pixels, uint32_t pixels_size); 76 77 void swapTextures(FrameworkFormat type, GLuint* textures); 78 79 // public so other classes can call 80 static void createYUVGLTex(GLenum textureUnit, 81 GLsizei width, 82 GLsizei height, 83 FrameworkFormat format, 84 YUVPlane plane, 85 GLuint* outTextureName); 86 private: 87 void init(int w, int h, FrameworkFormat format); 88 void reset(); 89 90 void createYUVGLShader(); 91 void createYUVGLFullscreenQuad(); 92 93 // For dealing with n-pixel-aligned buffers 94 void updateCutoffs(float yWidth, float yStridePixels, 95 float uvWidth, float uvStridePixels); 96 97 int mWidth = 0; 98 int mHeight = 0; 99 FrameworkFormat mFormat; 100 // colorbuffer w/h/format, could be different 101 FrameworkFormat mColorBufferFormat; 102 // We need the following GL objects: 103 GLuint mProgram = 0; 104 GLuint mQuadVertexBuffer = 0; 105 GLuint mQuadIndexBuffer = 0; 106 GLuint mTextureY = 0; 107 GLuint mTextureU = 0; 108 GLuint mTextureV = 0; 109 bool mTexturesSwapped = false; 110 GLint mUniformLocYWidthCutoff = -1; 111 GLint mUniformLocUVWidthCutoff = -1; 112 GLint mUniformLocSamplerY = -1; 113 GLint mUniformLocSamplerU = -1; 114 GLint mUniformLocSamplerV = -1; 115 GLint mAttributeLocPos = -1; 116 GLint mAttributeLocTexCoord = -1; 117 118 float mYWidthCutoff = 1.0; 119 float mUVWidthCutoff = 1.0; 120 bool mHasGlsl3Support = false; 121 122 // YUVConverter can end up being used 123 // in a TextureDraw / subwindow context, and subsequently 124 // overwrite the previous state. 125 // This section is so YUVConverter can be used in the middle 126 // of any GL context without impacting what's 127 // already going on there, by saving/restoring the state 128 // that it is impacting. 129 void saveGLState(); 130 void restoreGLState(); 131 // Impacted state 132 GLfloat mCurrViewport[4] = {}; 133 GLint mCurrTexUnit = 0; 134 GLint mCurrProgram = 0; 135 GLint mCurrTexBind = 0; 136 GLint mCurrVbo = 0; 137 GLint mCurrIbo = 0; 138 }; 139 140 } // namespace gl 141 } // namespace gfxstream 142