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