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 : int { 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 bool yuv420888ToNv21); 64 // destroy when ColorBuffer is destroyed 65 ~YUVConverter(); 66 // call when gralloc_unlock updates 67 // the host color buffer 68 // (rcUpdateColorBuffer) 69 void drawConvert(int x, int y, int width, int height, const char* pixels); 70 void drawConvertFromFormat(FrameworkFormat format, int x, int y, int width, int height, 71 const char* pixels, void* metadata = nullptr); 72 73 uint32_t getDataSize(); 74 // read YUV data into pixels, exactly pixels_size bytes; 75 // if size mismatches, will read nothing. 76 void readPixels(uint8_t* pixels, uint32_t pixels_size); 77 78 void swapTextures(FrameworkFormat type, GLuint* textures, void* metadata = nullptr); 79 80 // public so other classes can call 81 static void createYUVGLTex(GLenum textureUnit, 82 GLsizei width, 83 GLsizei height, 84 FrameworkFormat format, 85 bool yuv420888ToNv21, 86 YUVPlane plane, 87 GLuint* outTextureName); 88 private: 89 void init(int w, int h, FrameworkFormat format); 90 void reset(); 91 92 void createYUVGLShader(); 93 void createYUVGLFullscreenQuad(); 94 95 // For dealing with n-pixel-aligned buffers 96 void updateCutoffs(float yWidth, float yStridePixels, 97 float uvWidth, float uvStridePixels); 98 99 int mWidth = 0; 100 int mHeight = 0; 101 FrameworkFormat mFormat; 102 // colorbuffer w/h/format, could be different 103 FrameworkFormat mColorBufferFormat; 104 // We need the following GL objects: 105 GLuint mProgram = 0; 106 GLuint mQuadVertexBuffer = 0; 107 GLuint mQuadIndexBuffer = 0; 108 GLuint mTextureY = 0; 109 GLuint mTextureU = 0; 110 GLuint mTextureV = 0; 111 bool mTexturesSwapped = false; 112 GLint mUniformLocYWidthCutoff = -1; 113 GLint mUniformLocUVWidthCutoff = -1; 114 GLint mUniformLocSamplerY = -1; 115 GLint mUniformLocSamplerU = -1; 116 GLint mUniformLocSamplerV = -1; 117 GLint mAttributeLocPos = -1; 118 GLint mAttributeLocTexCoord = -1; 119 120 float mYWidthCutoff = 1.0; 121 float mUVWidthCutoff = 1.0; 122 bool mHasGlsl3Support = false; 123 bool mYuv420888ToNv21 = false; 124 125 // YUVConverter can end up being used 126 // in a TextureDraw / subwindow context, and subsequently 127 // overwrite the previous state. 128 // This section is so YUVConverter can be used in the middle 129 // of any GL context without impacting what's 130 // already going on there, by saving/restoring the state 131 // that it is impacting. 132 void saveGLState(); 133 void restoreGLState(); 134 // Impacted state 135 GLfloat mCurrViewport[4] = {}; 136 GLint mCurrTexUnit = 0; 137 GLint mCurrProgram = 0; 138 GLint mCurrTexBind = 0; 139 GLint mCurrVbo = 0; 140 GLint mCurrIbo = 0; 141 142 // color aspects related information 143 uint64_t mColorPrimaries = 4; // this is 601, the default 144 uint64_t mColorRange = 2; // this is limited range, the default 145 uint64_t mColorTransfer = 3; // this is the default 146 147 bool checkAndUpdateColorAspectsChanged(void* metadata); 148 }; 149 150 } // namespace gl 151 } // namespace gfxstream 152