| // Copyright (C) 2022 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "DisplayGl.h" |
| |
| #include "DisplaySurfaceGl.h" |
| #include "OpenGLESDispatch/DispatchTables.h" |
| #include "OpenGLESDispatch/EGLDispatch.h" |
| #include "TextureDraw.h" |
| #include "host-common/logging.h" |
| |
| namespace gfxstream { |
| namespace gl { |
| namespace { |
| |
| std::shared_future<void> getCompletedFuture() { |
| std::shared_future<void> completedFuture = |
| std::async(std::launch::deferred, [] {}).share(); |
| completedFuture.wait(); |
| return completedFuture; |
| } |
| |
| } // namespace |
| |
| std::shared_future<void> DisplayGl::post(const Post& post) { |
| const auto* surface = getBoundSurface(); |
| if (!surface) { |
| return getCompletedFuture(); |
| } |
| const auto* surfaceGl = static_cast<const DisplaySurfaceGl*>(surface->getImpl()); |
| |
| bool hasDrawLayer = false; |
| for (const PostLayer& layer : post.layers) { |
| if (layer.layerOptions) { |
| if (!hasDrawLayer) { |
| mTextureDraw->prepareForDrawLayer(); |
| hasDrawLayer = true; |
| } |
| layer.colorBuffer->glOpPostLayer(*layer.layerOptions, post.frameWidth, |
| post.frameHeight); |
| } else if (layer.overlayOptions) { |
| if (hasDrawLayer) { |
| ERR("Cannot mix colorBuffer.postLayer with postWithOverlay!"); |
| } |
| layer.colorBuffer->glOpPostViewportScaledWithOverlay( |
| layer.overlayOptions->rotation, layer.overlayOptions->dx, layer.overlayOptions->dy); |
| } |
| } |
| if (hasDrawLayer) { |
| mTextureDraw->cleanupForDrawLayer(); |
| } |
| |
| s_egl.eglSwapBuffers(surfaceGl->mDisplay, surfaceGl->mSurface); |
| |
| return getCompletedFuture(); |
| } |
| |
| void DisplayGl::viewport(int width, int height) { |
| mViewportWidth = width; |
| mViewportHeight = height; |
| s_gles2.glViewport(0, 0, mViewportWidth, mViewportHeight); |
| } |
| |
| void DisplayGl::clear() { |
| const auto* surface = getBoundSurface(); |
| if (!surface) { |
| return; |
| } |
| const auto* surfaceGl = static_cast<const DisplaySurfaceGl*>(surface->getImpl()); |
| #ifndef __linux__ |
| s_gles2.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
| s_egl.eglSwapBuffers(surfaceGl->mDisplay, surfaceGl->mSurface); |
| #endif |
| } |
| |
| } // namespace gl |
| } // namespace gfxstream |