• 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_common.h"
31 
32 #define __CLASS__ "GLCommon"
33 
34 namespace sdm {
35 
LoadProgram(int vertex_entries,const char ** vertex,int fragment_entries,const char ** fragment)36 GLuint GLCommon::LoadProgram(int vertex_entries, const char **vertex, int fragment_entries,
37                            const char **fragment) {
38   GLuint prog_id = glCreateProgram();
39 
40   int vert_id = glCreateShader(GL_VERTEX_SHADER);
41   int frag_id = glCreateShader(GL_FRAGMENT_SHADER);
42 
43   GL(glShaderSource(vert_id, vertex_entries, vertex, 0));
44   GL(glCompileShader(vert_id));
45   DumpShaderLog(vert_id);
46 
47   GL(glShaderSource(frag_id, fragment_entries, fragment, 0));
48   GL(glCompileShader(frag_id));
49   DumpShaderLog(frag_id);
50 
51   GL(glAttachShader(prog_id, vert_id));
52   GL(glAttachShader(prog_id, frag_id));
53 
54   GL(glLinkProgram(prog_id));
55 
56   GL(glDetachShader(prog_id, vert_id));
57   GL(glDetachShader(prog_id, frag_id));
58 
59   GL(glDeleteShader(vert_id));
60   GL(glDeleteShader(frag_id));
61 
62   return prog_id;
63 }
64 
DumpShaderLog(int shader)65 void GLCommon::DumpShaderLog(int shader) {
66   int success = 0;
67   GLchar infoLog[512];
68   GL(glGetShaderiv(shader, GL_COMPILE_STATUS, &success));
69   if (!success) {
70     glGetShaderInfoLog(shader, 512, NULL, infoLog);
71     DLOGI("Shader Failed to compile: %s\n", infoLog);
72   }
73 }
74 
MakeCurrent(const GLContext * ctx)75 void GLCommon::MakeCurrent(const GLContext* ctx) {
76   DTRACE_SCOPED();
77   EGL(eglMakeCurrent(ctx->egl_display, ctx->egl_surface, ctx->egl_surface, ctx->egl_context));
78 }
79 
SetProgram(uint32_t id)80 void GLCommon::SetProgram(uint32_t id) {
81   DTRACE_SCOPED();
82   GL(glUseProgram(id));
83 }
84 
DeleteProgram(uint32_t id)85 void GLCommon::DeleteProgram(uint32_t id) {
86   DTRACE_SCOPED();
87   GL(glDeleteProgram(id));
88 }
89 
SetSourceBuffer(const private_handle_t * src_hnd)90 void GLCommon::SetSourceBuffer(const private_handle_t *src_hnd) {
91   DTRACE_SCOPED();
92   EGLImageBuffer *src_buffer = image_wrapper_.wrap(reinterpret_cast<const void *>(src_hnd));
93 
94   GL(glActiveTexture(GL_TEXTURE0));
95   if (src_buffer) {
96     GL(glBindTexture(GL_TEXTURE_2D, src_buffer->getTexture(GL_TEXTURE_2D)));
97   }
98 }
99 
SetDestinationBuffer(const private_handle_t * dst_hnd,const GLRect & dst_rect)100 void GLCommon::SetDestinationBuffer(const private_handle_t *dst_hnd, const GLRect &dst_rect) {
101   DTRACE_SCOPED();
102   EGLImageBuffer *dst_buffer = image_wrapper_.wrap(reinterpret_cast<const void *>(dst_hnd));
103 
104   if (dst_buffer) {
105     GL(glBindFramebuffer(GL_FRAMEBUFFER, dst_buffer->getFramebuffer()));
106     float width = dst_rect.right - dst_rect.left;
107     float height = dst_rect.bottom - dst_rect.top;
108     GL(glViewport(dst_rect.left, dst_rect.top, width, height));
109   }
110 }
111 
WaitOnInputFence(const shared_ptr<Fence> & in_fence)112 int GLCommon::WaitOnInputFence(const shared_ptr<Fence> &in_fence) {
113   DTRACE_SCOPED();
114 
115   int fd = Fence::Dup(in_fence);
116   EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fd, EGL_NONE};
117   EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID,
118                                      attribs);
119 
120   if (sync == EGL_NO_SYNC_KHR) {
121     DLOGE("Failed to create sync from source fd: %s", Fence::GetStr(in_fence).c_str());
122     close(fd);
123     return -1;
124   }
125 
126   EGL(eglWaitSyncKHR(eglGetCurrentDisplay(), sync, 0));
127   EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
128 
129   return 0;
130 }
131 
CreateOutputFence(shared_ptr<Fence> * out_fence)132 int GLCommon::CreateOutputFence(shared_ptr<Fence> *out_fence) {
133   DTRACE_SCOPED();
134   EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
135 
136   // Swap buffer.
137   GL(glFlush());
138 
139   if (sync == EGL_NO_SYNC_KHR) {
140     DLOGE("Failed to create egl sync fence");
141     return -1;
142   }
143 
144   int status = 0;
145   int fd = eglDupNativeFenceFDANDROID(eglGetCurrentDisplay(), sync);
146   if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
147     status = -1;
148     DLOGE("Failed to dup sync");
149   } else {
150     *out_fence = Fence::Create(fd, "gl_out_fence");
151   }
152   EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
153 
154   return status;
155 }
156 
DestroyContext(GLContext * ctx)157 void GLCommon::DestroyContext(GLContext* ctx) {
158   DTRACE_SCOPED();
159 
160   // Clear egl image buffers.
161   image_wrapper_.Deinit();
162 
163   EGL(DeleteProgram(ctx->program_id));
164   EGL(eglMakeCurrent(ctx->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
165   EGL(eglDestroySurface(ctx->egl_display, ctx->egl_surface));
166   EGL(eglDestroyContext(ctx->egl_display, ctx->egl_context));
167   EGL(eglTerminate(ctx->egl_display));
168 }
169 
ClearCache()170 void GLCommon::ClearCache() {
171   // Clear cached handles.
172   image_wrapper_.Deinit();
173   image_wrapper_.Init();
174 }
175 
SetRealTimePriority()176 void GLCommon::SetRealTimePriority() {
177   // same as composer thread
178   struct sched_param param = {0};
179   param.sched_priority = 2;
180   if (sched_setscheduler(0, SCHED_FIFO | SCHED_RESET_ON_FORK, &param) != 0) {
181     DLOGE("Couldn't set SCHED_FIFO: %d", errno);
182   }
183 }
184 
185 }  // namespace sdm
186 
187