blob: a31103ef635ba9ffd605e74d0567358c536d6925 [file] [log] [blame]
Lingfeng Yangee4aea32020-10-29 08:52:13 -07001/*
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>
Jason Macnak7cbc4d12022-03-29 16:19:48 -070027
Jason Macnaked0c9e62023-03-30 15:58:24 -070028namespace gfxstream {
29namespace gl {
30
AdityaK82886e42023-11-21 16:54:11 -080031enum class YUVPlane : int {
Jason Macnak7cbc4d12022-03-29 16:19:48 -070032 Y = 0,
33 U = 1,
34 V = 2,
35 UV = 3,
36};
37
Lingfeng Yangee4aea32020-10-29 08:52:13 -070038// 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().
58class YUVConverter {
59public:
60 // call ctor when creating a gralloc buffer
61 // with YUV format
Jason Macnak26872122024-02-23 10:46:09 -080062 YUVConverter(int width, int height, FrameworkFormat format,
63 bool yuv420888ToNv21);
Lingfeng Yangee4aea32020-10-29 08:52:13 -070064 // destroy when ColorBuffer is destroyed
65 ~YUVConverter();
66 // call when gralloc_unlock updates
67 // the host color buffer
68 // (rcUpdateColorBuffer)
Jason Macnak9f18b952022-03-29 15:56:35 -070069 void drawConvert(int x, int y, int width, int height, const char* pixels);
Lingfeng Yang63a26f92021-04-14 13:43:42 -070070 void drawConvertFromFormat(FrameworkFormat format, int x, int y, int width, int height,
Bo Hue1a53fa2023-06-27 13:53:46 -070071 const char* pixels, void* metadata = nullptr);
Lingfeng Yangee4aea32020-10-29 08:52:13 -070072
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
Bo Hue1a53fa2023-06-27 13:53:46 -070078 void swapTextures(FrameworkFormat type, GLuint* textures, void* metadata = nullptr);
Lingfeng Yangee4aea32020-10-29 08:52:13 -070079
Lingfeng Yangee4aea32020-10-29 08:52:13 -070080 // public so other classes can call
Jason Macnak93165222022-03-29 17:03:04 -070081 static void createYUVGLTex(GLenum textureUnit,
Lingfeng Yangee4aea32020-10-29 08:52:13 -070082 GLsizei width,
83 GLsizei height,
Jason Macnak93165222022-03-29 17:03:04 -070084 FrameworkFormat format,
Jason Macnak26872122024-02-23 10:46:09 -080085 bool yuv420888ToNv21,
Jason Macnak93165222022-03-29 17:03:04 -070086 YUVPlane plane,
87 GLuint* outTextureName);
Lingfeng Yangee4aea32020-10-29 08:52:13 -070088private:
89 void init(int w, int h, FrameworkFormat format);
90 void reset();
91
Jason Macnak98ec0262022-03-30 12:36:52 -070092 void createYUVGLShader();
93 void createYUVGLFullscreenQuad();
94
Lingfeng Yangee4aea32020-10-29 08:52:13 -070095 // For dealing with n-pixel-aligned buffers
Jason Macnaka5a82502022-10-20 07:46:34 -070096 void updateCutoffs(float yWidth, float yStridePixels,
97 float uvWidth, float uvStridePixels);
Jason Macnak98ec0262022-03-30 12:36:52 -070098
Lingfeng Yangee4aea32020-10-29 08:52:13 -070099 int mWidth = 0;
100 int mHeight = 0;
101 FrameworkFormat mFormat;
102 // colorbuffer w/h/format, could be different
Jason Macnak9f18b952022-03-29 15:56:35 -0700103 FrameworkFormat mColorBufferFormat;
Lingfeng Yangee4aea32020-10-29 08:52:13 -0700104 // We need the following GL objects:
105 GLuint mProgram = 0;
Jason Macnak9f18b952022-03-29 15:56:35 -0700106 GLuint mQuadVertexBuffer = 0;
107 GLuint mQuadIndexBuffer = 0;
108 GLuint mTextureY = 0;
109 GLuint mTextureU = 0;
110 GLuint mTextureV = 0;
Lingfeng Yang63a26f92021-04-14 13:43:42 -0700111 bool mTexturesSwapped = false;
Jason Macnak9f18b952022-03-29 15:56:35 -0700112 GLint mUniformLocYWidthCutoff = -1;
Jason Macnaka5a82502022-10-20 07:46:34 -0700113 GLint mUniformLocUVWidthCutoff = -1;
Jason Macnak9f18b952022-03-29 15:56:35 -0700114 GLint mUniformLocSamplerY = -1;
115 GLint mUniformLocSamplerU = -1;
116 GLint mUniformLocSamplerV = -1;
Jason Macnak9f18b952022-03-29 15:56:35 -0700117 GLint mAttributeLocPos = -1;
Jason Macnak98ec0262022-03-30 12:36:52 -0700118 GLint mAttributeLocTexCoord = -1;
119
Lingfeng Yangee4aea32020-10-29 08:52:13 -0700120 float mYWidthCutoff = 1.0;
Jason Macnaka5a82502022-10-20 07:46:34 -0700121 float mUVWidthCutoff = 1.0;
Jason Macnak98ec0262022-03-30 12:36:52 -0700122 bool mHasGlsl3Support = false;
Jason Macnak26872122024-02-23 10:46:09 -0800123 bool mYuv420888ToNv21 = false;
Lingfeng Yangee4aea32020-10-29 08:52:13 -0700124
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;
Bo Hue1a53fa2023-06-27 13:53:46 -0700141
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);
Lingfeng Yangee4aea32020-10-29 08:52:13 -0700148};
Jason Macnaked0c9e62023-03-30 15:58:24 -0700149
150} // namespace gl
151} // namespace gfxstream