blob: 8245e5fe739b329064a6b8d5e90ccfc527d5dea8 [file] [log] [blame]
Pullakavi Srinivas17495f12019-09-16 20:25:20 +05301/*
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +05302 * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
Pullakavi Srinivas17495f12019-09-16 20:25:20 +05303 *
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
Pullakavi Srinivas4b413e72020-03-27 00:13:44 +053030#include <vector>
31#include <string>
32
Pullakavi Srinivas17495f12019-09-16 20:25:20 +053033#include "gl_common.h"
34
35#define __CLASS__ "GLCommon"
36
37namespace sdm {
38
39GLuint GLCommon::LoadProgram(int vertex_entries, const char **vertex, int fragment_entries,
40 const char **fragment) {
41 GLuint prog_id = glCreateProgram();
42
43 int vert_id = glCreateShader(GL_VERTEX_SHADER);
44 int frag_id = glCreateShader(GL_FRAGMENT_SHADER);
45
46 GL(glShaderSource(vert_id, vertex_entries, vertex, 0));
47 GL(glCompileShader(vert_id));
48 DumpShaderLog(vert_id);
49
50 GL(glShaderSource(frag_id, fragment_entries, fragment, 0));
51 GL(glCompileShader(frag_id));
52 DumpShaderLog(frag_id);
53
54 GL(glAttachShader(prog_id, vert_id));
55 GL(glAttachShader(prog_id, frag_id));
56
57 GL(glLinkProgram(prog_id));
58
59 GL(glDetachShader(prog_id, vert_id));
60 GL(glDetachShader(prog_id, frag_id));
61
62 GL(glDeleteShader(vert_id));
63 GL(glDeleteShader(frag_id));
64
65 return prog_id;
66}
67
68void GLCommon::DumpShaderLog(int shader) {
69 int success = 0;
70 GLchar infoLog[512];
71 GL(glGetShaderiv(shader, GL_COMPILE_STATUS, &success));
72 if (!success) {
73 glGetShaderInfoLog(shader, 512, NULL, infoLog);
74 DLOGI("Shader Failed to compile: %s\n", infoLog);
75 }
76}
77
78void GLCommon::MakeCurrent(const GLContext* ctx) {
79 DTRACE_SCOPED();
80 EGL(eglMakeCurrent(ctx->egl_display, ctx->egl_surface, ctx->egl_surface, ctx->egl_context));
81}
82
83void GLCommon::SetProgram(uint32_t id) {
84 DTRACE_SCOPED();
85 GL(glUseProgram(id));
86}
87
88void GLCommon::DeleteProgram(uint32_t id) {
89 DTRACE_SCOPED();
90 GL(glDeleteProgram(id));
91}
92
93void GLCommon::SetSourceBuffer(const private_handle_t *src_hnd) {
94 DTRACE_SCOPED();
95 EGLImageBuffer *src_buffer = image_wrapper_.wrap(reinterpret_cast<const void *>(src_hnd));
96
97 GL(glActiveTexture(GL_TEXTURE0));
98 if (src_buffer) {
99 GL(glBindTexture(GL_TEXTURE_2D, src_buffer->getTexture(GL_TEXTURE_2D)));
100 }
101}
102
Pullakavi Srinivas295a3732020-05-06 00:52:00 +0530103void GLCommon::SetDestinationBuffer(const private_handle_t *dst_hnd, bool force_set) {
Pullakavi Srinivas17495f12019-09-16 20:25:20 +0530104 DTRACE_SCOPED();
Pullakavi Srinivas295a3732020-05-06 00:52:00 +0530105 if (!force_set && (dst_hnd_ == dst_hnd)) {
Pullakavi Srinivas4b413e72020-03-27 00:13:44 +0530106 return;
107 }
Pullakavi Srinivas17495f12019-09-16 20:25:20 +0530108 EGLImageBuffer *dst_buffer = image_wrapper_.wrap(reinterpret_cast<const void *>(dst_hnd));
109
110 if (dst_buffer) {
111 GL(glBindFramebuffer(GL_FRAMEBUFFER, dst_buffer->getFramebuffer()));
Pullakavi Srinivas17495f12019-09-16 20:25:20 +0530112 }
Pullakavi Srinivas4b413e72020-03-27 00:13:44 +0530113
114 // Same buffer gets reprogrammed. Avoid repeated setting.
115 dst_hnd_ = dst_hnd;
Pullakavi Srinivas17495f12019-09-16 20:25:20 +0530116}
117
Pullakavi Srinivas4b413e72020-03-27 00:13:44 +0530118int GLCommon::WaitOnInputFence(const std::vector<shared_ptr<Fence>> &in_fences) {
Pullakavi Srinivas17495f12019-09-16 20:25:20 +0530119 DTRACE_SCOPED();
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +0530120
Pullakavi Srinivas4b413e72020-03-27 00:13:44 +0530121 shared_ptr<Fence> in_fence = Fence::Merge(in_fences, true /* ignore signaled*/);
122 if (in_fence == nullptr) {
123 return 0;
124 }
125
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +0530126 int fd = Fence::Dup(in_fence);
127 EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fd, EGL_NONE};
Pullakavi Srinivas17495f12019-09-16 20:25:20 +0530128 EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID,
129 attribs);
130
131 if (sync == EGL_NO_SYNC_KHR) {
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +0530132 DLOGE("Failed to create sync from source fd: %s", Fence::GetStr(in_fence).c_str());
133 close(fd);
Pullakavi Srinivas17495f12019-09-16 20:25:20 +0530134 return -1;
Pullakavi Srinivas17495f12019-09-16 20:25:20 +0530135 }
136
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +0530137 EGL(eglWaitSyncKHR(eglGetCurrentDisplay(), sync, 0));
138 EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
139
Pullakavi Srinivas17495f12019-09-16 20:25:20 +0530140 return 0;
141}
142
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +0530143int GLCommon::CreateOutputFence(shared_ptr<Fence> *out_fence) {
Pullakavi Srinivas17495f12019-09-16 20:25:20 +0530144 DTRACE_SCOPED();
Pullakavi Srinivas17495f12019-09-16 20:25:20 +0530145 EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
146
147 // Swap buffer.
148 GL(glFlush());
149
150 if (sync == EGL_NO_SYNC_KHR) {
151 DLOGE("Failed to create egl sync fence");
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +0530152 return -1;
Pullakavi Srinivas17495f12019-09-16 20:25:20 +0530153 }
154
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +0530155 int status = 0;
156 int fd = eglDupNativeFenceFDANDROID(eglGetCurrentDisplay(), sync);
157 if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
158 status = -1;
159 DLOGE("Failed to dup sync");
160 } else {
Dileep Marchya58928122020-01-28 12:16:51 +0530161 *out_fence = Fence::Create(fd, "gl_out_fence");
Rajavenu Kyatham7338b9e2019-12-30 19:52:16 +0530162 }
163 EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
164
165 return status;
Pullakavi Srinivas17495f12019-09-16 20:25:20 +0530166}
167
Pullakavi Srinivas1c87eee2019-11-05 20:08:31 +0530168void GLCommon::DestroyContext(GLContext* ctx) {
Pullakavi Srinivas17495f12019-09-16 20:25:20 +0530169 DTRACE_SCOPED();
Pullakavi Srinivas1c87eee2019-11-05 20:08:31 +0530170
171 // Clear egl image buffers.
172 image_wrapper_.Deinit();
173
174 EGL(DeleteProgram(ctx->program_id));
Pullakavi Srinivas17495f12019-09-16 20:25:20 +0530175 EGL(eglMakeCurrent(ctx->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
176 EGL(eglDestroySurface(ctx->egl_display, ctx->egl_surface));
177 EGL(eglDestroyContext(ctx->egl_display, ctx->egl_context));
Pullakavi Srinivas17495f12019-09-16 20:25:20 +0530178 EGL(eglTerminate(ctx->egl_display));
179}
180
Pullakavi Srinivasc99bd742019-12-14 18:15:17 +0530181void GLCommon::ClearCache() {
182 // Clear cached handles.
183 image_wrapper_.Deinit();
184 image_wrapper_.Init();
185}
186
Pullakavi Srinivasbf857702020-03-12 16:55:12 +0530187void GLCommon::SetRealTimePriority() {
188 // same as composer thread
189 struct sched_param param = {0};
190 param.sched_priority = 2;
191 if (sched_setscheduler(0, SCHED_FIFO | SCHED_RESET_ON_FORK, &param) != 0) {
192 DLOGE("Couldn't set SCHED_FIFO: %d", errno);
193 }
194}
195
Pullakavi Srinivas4b413e72020-03-27 00:13:44 +0530196void GLCommon::SetViewport(const GLRect &dst_rect) {
197 DTRACE_SCOPED();
198 float width = dst_rect.right - dst_rect.left;
199 float height = dst_rect.bottom - dst_rect.top;
200 GL(glViewport(dst_rect.left, dst_rect.top, width, height));
201}
202
Pullakavi Srinivas17495f12019-09-16 20:25:20 +0530203} // namespace sdm
204