1 // Copyright (C) 2022 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "DisplayGl.h"
16 
17 #include "DisplaySurfaceGl.h"
18 #include "OpenGLESDispatch/DispatchTables.h"
19 #include "OpenGLESDispatch/EGLDispatch.h"
20 #include "TextureDraw.h"
21 #include "host-common/logging.h"
22 
23 namespace gfxstream {
24 namespace gl {
25 namespace {
26 
getCompletedFuture()27 std::shared_future<void> getCompletedFuture() {
28     std::shared_future<void> completedFuture =
29         std::async(std::launch::deferred, [] {}).share();
30     completedFuture.wait();
31     return completedFuture;
32 }
33 
34 }  // namespace
35 
post(const Post & post)36 std::shared_future<void> DisplayGl::post(const Post& post) {
37     const auto* surface = getBoundSurface();
38     if (!surface) {
39         return getCompletedFuture();
40     }
41     if (post.layers.empty()) {
42         clear();
43         return getCompletedFuture();
44     }
45     const auto* surfaceGl = static_cast<const DisplaySurfaceGl*>(surface->getImpl());
46 
47     bool hasDrawLayer = false;
48     for (const PostLayer& layer : post.layers) {
49         if (layer.layerOptions) {
50             if (!hasDrawLayer) {
51                 mTextureDraw->prepareForDrawLayer();
52                 hasDrawLayer = true;
53             }
54             layer.colorBuffer->glOpPostLayer(*layer.layerOptions, post.frameWidth,
55                                              post.frameHeight);
56         } else if (layer.overlayOptions) {
57             if (hasDrawLayer) {
58                 ERR("Cannot mix colorBuffer.postLayer with postWithOverlay!");
59             }
60             layer.colorBuffer->glOpPostViewportScaledWithOverlay(
61                 layer.overlayOptions->rotation, layer.overlayOptions->dx, layer.overlayOptions->dy);
62         }
63     }
64     if (hasDrawLayer) {
65         mTextureDraw->cleanupForDrawLayer();
66     }
67 
68     s_egl.eglSwapBuffers(surfaceGl->mDisplay, surfaceGl->mSurface);
69 
70     return getCompletedFuture();
71 }
72 
viewport(int width,int height)73 void DisplayGl::viewport(int width, int height) {
74     mViewportWidth = width;
75     mViewportHeight = height;
76     s_gles2.glViewport(0, 0, mViewportWidth, mViewportHeight);
77 }
78 
clear()79 void DisplayGl::clear() {
80     const auto* surface = getBoundSurface();
81     if (!surface) {
82         return;
83     }
84     const auto* surfaceGl = static_cast<const DisplaySurfaceGl*>(surface->getImpl());
85 #ifndef __linux__
86     s_gles2.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
87     s_egl.eglSwapBuffers(surfaceGl->mDisplay, surfaceGl->mSurface);
88 #endif
89 }
90 
91 }  // namespace gl
92 }  // namespace gfxstream
93