• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7     * Redistributions of source code must retain the above copyright
8       notice, this list of conditions and the following disclaimer.
9     * Redistributions in binary form must reproduce the above
10       copyright notice, this list of conditions and the following
11       disclaimer in the documentation and/or other materials provided
12       with the distribution.
13     * Neither the name of The Linux Foundation nor the names of its
14       contributors may be used to endorse or promote products derived
15       from this software without specific prior written permission.
16 
17  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "gl_color_convert_impl.h"
31 
32 #define __CLASS__ "GLColorConvertImpl"
33 
34 namespace sdm {
35 
36 const float kFullScreenVertices[] = {
37   -1.0f,  3.0f,
38   -1.0f, -1.0f,
39   3.0f, -1.0f
40 };
41 
42 const float kFullScreenTexCoords[] = {
43   0.0f, 2.0f,
44   0.0f, 0.0f,
45   2.0f, 0.0f
46 };
47 
48 const char* kVertexShader = ""
49   "#version 300 es                                                       \n"
50   "precision highp float;                                                \n"
51   "layout(location = 0) in vec2 in_pos;                                  \n"
52   "layout(location = 1) in vec2 in_uv;                                   \n"
53   "                                                                      \n"
54   "out vec2 uv;                                                          \n"
55   "                                                                      \n"
56   "void main()                                                           \n"
57   "{                                                                     \n"
58   "    gl_Position = vec4(in_pos, 0.0, 1.0);                             \n"
59   "    uv = in_uv;                                                       \n"
60   "}                                                                     \n";
61 
62 const char* kConvertRgbToYuvShader = ""
63   "#extension GL_EXT_YUV_target : require                                \n"
64   "precision highp float;                                                \n"
65   "                                                                      \n"
66   "layout(binding = 0) uniform sampler2D u_sTexture;                     \n"
67   "                                                                      \n"
68   "in vec2 uv;                                                           \n"
69   "layout (yuv) out vec4 color;                                          \n"
70   "                                                                      \n"
71   "void main()                                                           \n"
72   "{                                                                     \n"
73   "    vec3 rgbColor = texture(u_sTexture, uv).rgb;                      \n"
74   "    color = vec4(rgb_2_yuv(rgbColor, itu_601_full_range), 1.0);       \n"
75   "}                                                                     \n";
76 
CreateContext(GLRenderTarget target,bool secure)77 int GLColorConvertImpl::CreateContext(GLRenderTarget target, bool secure) {
78   if (target != kTargetRGBA && target != kTargetYUV) {
79     DLOGE("Invalid GLRenderTarget: %d", target);
80     return -1;
81   }
82 
83   ctx_.egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
84   EGL(eglBindAPI(EGL_OPENGL_ES_API));
85 
86   // Initialize current display.
87   EGL(eglInitialize(ctx_.egl_display, nullptr, nullptr));
88 
89   // Get attributes corresponing to render target.
90   // Describes Framebuffer attributes like buffer depth, color space etc;
91   EGLConfig eglConfig;
92   int numConfig = 0;
93   if (target == kTargetRGBA) {
94     EGLint eglConfigAttribList[] = {EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
95                                     EGL_RED_SIZE,     8,
96                                     EGL_GREEN_SIZE,   8,
97                                     EGL_BLUE_SIZE,    8,
98                                     EGL_ALPHA_SIZE,   8,
99                                     EGL_NONE};
100     EGL(eglChooseConfig(ctx_.egl_display, eglConfigAttribList, &eglConfig, 1, &numConfig));
101   } else {
102     EGLint eglConfigAttribList[] = {EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
103                                     EGL_RENDERABLE_TYPE,           EGL_OPENGL_ES2_BIT,
104                                     EGL_COLOR_BUFFER_TYPE,         EGL_YUV_BUFFER_EXT,
105                                     EGL_YUV_ORDER_EXT,             EGL_YUV_ORDER_YUV_EXT,
106                                     EGL_YUV_NUMBER_OF_PLANES_EXT,  2,
107                                     EGL_YUV_SUBSAMPLE_EXT,         EGL_YUV_SUBSAMPLE_4_2_0_EXT,
108                                     EGL_YUV_DEPTH_RANGE_EXT,       EGL_YUV_DEPTH_RANGE_LIMITED_EXT,
109                                     EGL_YUV_CSC_STANDARD_EXT,      EGL_YUV_CSC_STANDARD_601_EXT,
110                                     EGL_YUV_PLANE_BPP_EXT,         EGL_YUV_PLANE_BPP_8_EXT,
111                                     EGL_NONE};
112     EGL(eglChooseConfig(ctx_.egl_display, eglConfigAttribList, &eglConfig, 1, &numConfig));
113   }
114 
115   // When GPU runs in protected context it can read from
116   //  - Protected sources
117   //  - UnProtected source
118   // and writes into Protected buffer.
119   // VS in UnProtected context it can read/write happen from/to Unprotected sources.
120   EGLint egl_contextAttribList[] = {EGL_CONTEXT_CLIENT_VERSION, 3,
121                                     secure ? EGL_PROTECTED_CONTENT_EXT : EGL_NONE,
122                                     secure ? EGL_TRUE : EGL_NONE,
123                                     EGL_NONE};
124   ctx_.egl_context = eglCreateContext(ctx_.egl_display, eglConfig, NULL, egl_contextAttribList);
125 
126   // eglCreatePbufferSurface creates an off-screen pixel buffer surface and returns its handle
127   EGLint egl_surfaceAttribList[] = {EGL_WIDTH, 1,
128                                     EGL_HEIGHT, 1,
129                                     secure ? EGL_PROTECTED_CONTENT_EXT : EGL_NONE,
130                                     secure ? EGL_TRUE : EGL_NONE,
131                                     EGL_NONE};
132   ctx_.egl_surface = eglCreatePbufferSurface(ctx_.egl_display, eglConfig, egl_surfaceAttribList);
133 
134   // eglMakeCurrent attaches rendering context to rendering surface.
135   MakeCurrent(&ctx_);
136 
137   DLOGI("Created context = %p", (void *)(&ctx_.egl_context));
138 
139   // Load Vertex and Fragment shaders.
140   const char *fragment_shaders[2] = { };
141   int count = 0;
142   const char *version = "#version 300 es\n";
143 
144   fragment_shaders[count++] = version;
145 
146   // ToDo: Add support to yuv_to_rgb shader.
147   fragment_shaders[count++] = kConvertRgbToYuvShader;
148 
149   ctx_.program_id = LoadProgram(1, &kVertexShader, count, fragment_shaders);
150 
151   SetRealTimePriority();
152 
153   return 0;
154 }
155 
Blit(const private_handle_t * src_hnd,const private_handle_t * dst_hnd,const GLRect & src_rect,const GLRect & dst_rect,const shared_ptr<Fence> & src_acquire_fence,const shared_ptr<Fence> & dst_acquire_fence,shared_ptr<Fence> * release_fence)156 int GLColorConvertImpl::Blit(const private_handle_t *src_hnd, const private_handle_t *dst_hnd,
157                              const GLRect &src_rect, const GLRect &dst_rect,
158                              const shared_ptr<Fence> &src_acquire_fence,
159                              const shared_ptr<Fence> &dst_acquire_fence,
160                              shared_ptr<Fence> *release_fence) {
161   DTRACE_SCOPED();
162   // eglMakeCurrent attaches rendering context to rendering surface.
163   MakeCurrent(&ctx_);
164 
165   SetProgram(ctx_.program_id);
166 
167   SetSourceBuffer(src_hnd);
168   SetDestinationBuffer(dst_hnd, dst_rect);
169 
170   glEnableVertexAttribArray(0);
171   glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, kFullScreenVertices);
172   glEnableVertexAttribArray(1);
173   glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, kFullScreenTexCoords);
174   glDrawArrays(GL_TRIANGLES, 0, 3);
175 
176   shared_ptr<Fence> in_fence = Fence::Merge(src_acquire_fence, dst_acquire_fence);
177   if (in_fence) {
178     WaitOnInputFence(in_fence);
179   }
180 
181   // Create output fence for client to wait on.
182   CreateOutputFence(release_fence);
183 
184   return 0;
185 }
186 
Init()187 int GLColorConvertImpl::Init() {
188   return CreateContext(target_, secure_);
189 }
190 
Deinit()191 int GLColorConvertImpl::Deinit() {
192   MakeCurrent(&ctx_);
193   DestroyContext(&ctx_);
194 
195   return 0;
196 }
197 
~GLColorConvertImpl()198 GLColorConvertImpl::~GLColorConvertImpl() {}
199 
GLColorConvertImpl(GLRenderTarget target,bool secure)200 GLColorConvertImpl::GLColorConvertImpl(GLRenderTarget target, bool secure) {
201   target_ = target;
202   secure_ = secure;
203 }
204 
Reset()205 void GLColorConvertImpl::Reset() {
206   ClearCache();
207 }
208 
209 }  // namespace sdm
210 
211