Revert "Add DisplayGl and DisplaySurfaceGl"
This reverts commit cb8d1e4f237be8d58e26de57ee0b67245a63a34f.
Reason for revert: Seeing issues with potential concurrent usage of the pbuffer context.
Bug: b/251366833
Bug: b/250847245
Change-Id: I39ba968339009ba8086b5f0c989aa5ba50f5a9aa
diff --git a/stream-servers/Android.bp b/stream-servers/Android.bp
index 2484f6a..b425bc6 100644
--- a/stream-servers/Android.bp
+++ b/stream-servers/Android.bp
@@ -59,8 +59,8 @@
"ChannelStream.cpp",
"ColorBuffer.cpp",
"Debug.cpp",
+ "Display.cpp",
"DisplaySurface.cpp",
- "DisplaySurfaceUser.cpp",
"FenceSync.cpp",
"Hwc2.cpp",
"PostWorker.cpp",
diff --git a/stream-servers/CMakeLists.txt b/stream-servers/CMakeLists.txt
index eb07d6b..53fe3f9 100644
--- a/stream-servers/CMakeLists.txt
+++ b/stream-servers/CMakeLists.txt
@@ -21,8 +21,8 @@
ChannelStream.cpp
ColorBuffer.cpp
Debug.cpp
+ Display.cpp
DisplaySurface.cpp
- DisplaySurfaceUser.cpp
FenceSync.cpp
Hwc2.cpp
PostWorker.cpp
diff --git a/stream-servers/ColorBuffer.cpp b/stream-servers/ColorBuffer.cpp
index 2a8303c..d3ca129 100644
--- a/stream-servers/ColorBuffer.cpp
+++ b/stream-servers/ColorBuffer.cpp
@@ -216,7 +216,6 @@
FrameworkFormat p_frameworkFormat,
HandleType hndl,
ContextHelper* helper,
- TextureDraw* textureDraw,
bool fastBlitSupported,
bool vulkanOnly) {
GLenum texFormat = 0;
@@ -236,7 +235,7 @@
* p_height;
// This constructor is private, so std::make_unique can't be used.
- std::unique_ptr<ColorBuffer> cb{new ColorBuffer(p_display, hndl, helper, textureDraw)};
+ std::unique_ptr<ColorBuffer> cb{new ColorBuffer(p_display, hndl, helper)};
cb->m_width = p_width;
cb->m_height = p_height;
cb->m_internalFormat = p_internalFormat;
@@ -331,9 +330,8 @@
return cb.release();
}
-ColorBuffer::ColorBuffer(EGLDisplay display, HandleType hndl, ContextHelper* helper,
- TextureDraw* textureDraw)
- : m_display(display), m_helper(helper), m_textureDraw(textureDraw), mHndl(hndl) {}
+ColorBuffer::ColorBuffer(EGLDisplay display, HandleType hndl, ContextHelper* helper)
+ : m_display(display), m_helper(helper), mHndl(hndl) {}
ColorBuffer::~ColorBuffer() {
if (m_vulkanOnly) {
@@ -801,7 +799,7 @@
s_gles2.glViewport(0, 0, m_width, m_height);
// render m_blitTex
- m_textureDraw->draw(m_blitTex, 0., 0, 0);
+ m_helper->getTextureDraw()->draw(m_blitTex, 0., 0, 0);
// Restore previous viewport.
s_gles2.glViewport(vport[0], vport[1], vport[2], vport[3]);
@@ -888,13 +886,13 @@
bool ColorBuffer::post(GLuint tex, float rotation, float dx, float dy) {
// NOTE: Do not call m_helper->setupContext() here!
waitSync();
- return m_textureDraw->draw(tex, rotation, dx, dy);
+ return m_helper->getTextureDraw()->draw(tex, rotation, dx, dy);
}
bool ColorBuffer::postWithOverlay(GLuint tex, float rotation, float dx, float dy) {
// NOTE: Do not call m_helper->setupContext() here!
waitSync();
- return m_textureDraw->drawWithOverlay(tex, rotation, dx, dy);
+ return m_helper->getTextureDraw()->drawWithOverlay(tex, rotation, dx, dy);
}
void ColorBuffer::readback(unsigned char* img, bool readbackBgra) {
@@ -955,7 +953,6 @@
ColorBuffer* ColorBuffer::onLoad(android::base::Stream* stream,
EGLDisplay p_display,
ContextHelper* helper,
- TextureDraw* textureDraw,
bool fastBlitSupported) {
HandleType hndl = static_cast<HandleType>(stream->getBe32());
GLuint width = static_cast<GLuint>(stream->getBe32());
@@ -969,9 +966,9 @@
if (!eglImage) {
return create(p_display, width, height, internalFormat, frameworkFormat,
- hndl, helper, textureDraw, fastBlitSupported);
+ hndl, helper, fastBlitSupported);
}
- ColorBuffer* cb = new ColorBuffer(p_display, hndl, helper, textureDraw);
+ ColorBuffer* cb = new ColorBuffer(p_display, hndl, helper);
cb->mNeedRestore = true;
cb->m_eglImage = eglImage;
cb->m_blitEGLImage = blitEGLImage;
@@ -1015,7 +1012,7 @@
void ColorBuffer::postLayer(const ComposeLayer& l, int frameWidth, int frameHeight) {
if (m_inUse) fprintf(stderr, "%s: cb in use\n", __func__);
waitSync();
- m_textureDraw->drawLayer(l, frameWidth, frameHeight, m_width, m_height, m_tex);
+ m_helper->getTextureDraw()->drawLayer(l, frameWidth, frameHeight, m_width, m_height, m_tex);
}
bool ColorBuffer::importMemory(ManagedDescriptor externalDescriptor, uint64_t size, bool dedicated,
diff --git a/stream-servers/ColorBuffer.h b/stream-servers/ColorBuffer.h
index 1ee5d34..10649d8 100644
--- a/stream-servers/ColorBuffer.h
+++ b/stream-servers/ColorBuffer.h
@@ -25,6 +25,7 @@
#include "BorrowedImage.h"
#include "ContextHelper.h"
+#include "DisplayVk.h"
#include "FrameworkFormats.h"
#include "Handle.h"
#include "Hwc2.h"
@@ -94,7 +95,6 @@
FrameworkFormat p_frameworkFormat,
HandleType hndl,
ContextHelper* helper,
- TextureDraw* textureDraw,
bool fastBlitSupported,
bool vulkanOnly = false);
@@ -202,7 +202,6 @@
static ColorBuffer* onLoad(android::base::Stream* stream,
EGLDisplay p_display,
ContextHelper* helper,
- TextureDraw* textureDraw,
bool fastBlitSupported);
HandleType getHndl() const;
@@ -238,8 +237,7 @@
void restore();
private:
- ColorBuffer(EGLDisplay display, HandleType hndl, ContextHelper* helper,
- TextureDraw* textureDraw);
+ ColorBuffer(EGLDisplay display, HandleType hndl, ContextHelper* helper);
// Helper function to get contents.
std::vector<uint8_t> getContents();
// Helper function to clear current EGL image.
@@ -278,7 +276,6 @@
EGLDisplay m_display = nullptr;
ContextHelper* m_helper = nullptr;
- TextureDraw* m_textureDraw = nullptr;
TextureResize* m_resizer = nullptr;
FrameworkFormat m_frameworkFormat;
GLuint m_yuv_conversion_fbo = 0; // FBO to offscreen-convert YUV to RGB
diff --git a/stream-servers/ContextHelper.h b/stream-servers/ContextHelper.h
index b4d0a22..3f14735 100644
--- a/stream-servers/ContextHelper.h
+++ b/stream-servers/ContextHelper.h
@@ -25,6 +25,7 @@
virtual ~ContextHelper() = default;
virtual bool setupContext() = 0;
virtual void teardownContext() = 0;
+ virtual TextureDraw* getTextureDraw() const = 0;
virtual bool isBound() const = 0;
};
diff --git a/stream-servers/DisplaySurfaceUser.cpp b/stream-servers/Display.cpp
similarity index 83%
rename from stream-servers/DisplaySurfaceUser.cpp
rename to stream-servers/Display.cpp
index 4abc885..a89f82d 100644
--- a/stream-servers/DisplaySurfaceUser.cpp
+++ b/stream-servers/Display.cpp
@@ -23,27 +23,27 @@
using emugl::ABORT_REASON_OTHER;
using emugl::FatalError;
-DisplaySurfaceUser::~DisplaySurfaceUser() {
+Display::~Display() {
if (mBoundSurface != nullptr) {
GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
- << "Failed to unbind a DisplaySurface before DisplaySurfaceUser destruction.";
+ << "Failed to unbind a DisplaySurface before Display destruction.";
}
}
-void DisplaySurfaceUser::bindToSurface(DisplaySurface* surface) {
+void Display::bindToSurface(DisplaySurface* surface) {
if (mBoundSurface != nullptr) {
GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
<< "Attempting to bind a DisplaySurface while another is already bound.";
}
this->bindToSurfaceImpl(surface);
- surface->registerUser(this);
+ surface->registerBoundDisplay(this);
mBoundSurface = surface;
}
-void DisplaySurfaceUser::unbindFromSurface() {
+void Display::unbindFromSurface() {
this->unbindFromSurfaceImpl();
- mBoundSurface->unregisterUser(this);
+ mBoundSurface->unregisterBoundDisplay(this);
mBoundSurface = nullptr;
}
diff --git a/stream-servers/Display.h b/stream-servers/Display.h
index 9a26223..4ed3062 100644
--- a/stream-servers/Display.h
+++ b/stream-servers/Display.h
@@ -14,13 +14,30 @@
#pragma once
-#include "DisplaySurfaceUser.h"
-
namespace gfxstream {
-class Display : public DisplaySurfaceUser {
+class Display;
+class DisplaySurface;
+
+class Display {
public:
- // TODO(b/233939967): move post()/viewport()/clear() interface here.
+ virtual ~Display();
+
+ public:
+ void bindToSurface(DisplaySurface* surface);
+
+ void unbindFromSurface();
+
+ protected:
+ virtual void bindToSurfaceImpl(DisplaySurface* surface) = 0;
+
+ virtual void unbindFromSurfaceImpl() = 0;
+
+ const DisplaySurface* getBoundSurface() const { return mBoundSurface; }
+
+ private:
+ friend class DisplaySurface;
+ DisplaySurface* mBoundSurface = nullptr;
};
-} // namespace gfxstream
\ No newline at end of file
+} // namespace gfxstream
diff --git a/stream-servers/DisplaySurface.cpp b/stream-servers/DisplaySurface.cpp
index 0c84b80..6a62a70 100644
--- a/stream-servers/DisplaySurface.cpp
+++ b/stream-servers/DisplaySurface.cpp
@@ -31,9 +31,9 @@
mImpl(std::move(impl)) {}
DisplaySurface::~DisplaySurface() {
- if (!mBoundUsers.empty()) {
+ if (mBoundDisplay) {
GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
- << "DisplaySurface destroyed while there are still users!";
+ << "DisplaySurface destroyed while still bound to a Display!";
}
}
@@ -53,12 +53,14 @@
mHeight = newHeight;
}
-void DisplaySurface::registerUser(DisplaySurfaceUser* user) {
- mBoundUsers.insert(user);
+void DisplaySurface::registerBoundDisplay(Display* display) {
+ mBoundDisplay = display;
}
-void DisplaySurface::unregisterUser(DisplaySurfaceUser* user) {
- mBoundUsers.erase(user);
+void DisplaySurface::unregisterBoundDisplay(Display* display) {
+ if (display == mBoundDisplay) {
+ mBoundDisplay = nullptr;
+ }
}
} // namespace gfxstream
diff --git a/stream-servers/DisplaySurface.h b/stream-servers/DisplaySurface.h
index 394bbdc..49bfd98 100644
--- a/stream-servers/DisplaySurface.h
+++ b/stream-servers/DisplaySurface.h
@@ -17,12 +17,11 @@
#include <cstdint>
#include <memory>
#include <mutex>
-#include <unordered_set>
namespace gfxstream {
+class Display;
class DisplaySurface;
-class DisplaySurfaceUser;
// Base class used for controlling the lifetime of a particular surface
// used for a display (e.g. EGLSurface or VkSurfaceKHR).
@@ -52,13 +51,13 @@
void updateSize(uint32_t newWidth, uint32_t newHeight);
private:
- friend class DisplaySurfaceUser;
+ friend class Display;
- void registerUser(DisplaySurfaceUser* user);
- void unregisterUser(DisplaySurfaceUser* user);
+ void registerBoundDisplay(Display* display);
+ void unregisterBoundDisplay(Display* display);
std::unique_ptr<DisplaySurfaceImpl> mImpl;
- std::unordered_set<DisplaySurfaceUser*> mBoundUsers;
+ Display* mBoundDisplay = nullptr;
mutable std::mutex mParamsMutex;
uint32_t mWidth = 0;
diff --git a/stream-servers/DisplaySurfaceUser.h b/stream-servers/DisplaySurfaceUser.h
deleted file mode 100644
index 0065709..0000000
--- a/stream-servers/DisplaySurfaceUser.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// 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.
-
-#pragma once
-
-namespace gfxstream {
-
-class DisplaySurface;
-class DisplaySurfaceUser;
-
-class DisplaySurfaceUser {
- public:
- virtual ~DisplaySurfaceUser();
-
- public:
- void bindToSurface(DisplaySurface* surface);
-
- void unbindFromSurface();
-
- protected:
- virtual void bindToSurfaceImpl(DisplaySurface* surface) = 0;
-
- virtual void unbindFromSurfaceImpl() = 0;
-
- const DisplaySurface* getBoundSurface() const { return mBoundSurface; }
-
- private:
- friend class DisplaySurface;
- DisplaySurface* mBoundSurface = nullptr;
-};
-
-} // namespace gfxstream
diff --git a/stream-servers/FrameBuffer.cpp b/stream-servers/FrameBuffer.cpp
index 503824b..a72d42b 100644
--- a/stream-servers/FrameBuffer.cpp
+++ b/stream-servers/FrameBuffer.cpp
@@ -49,7 +49,6 @@
#include "host-common/logging.h"
#include "host-common/misc.h"
#include "host-common/vm_operations.h"
-#include "vulkan/DisplayVk.h"
#include "vulkan/VkCommonOperations.h"
#include "vulkan/VkDecoderGlobalState.h"
@@ -82,6 +81,33 @@
GL_LOG("message:%s", message);
}
+// Implementation of a ColorBuffer::Helper instance that redirects calls
+// to a FrameBuffer instance.
+class FrameBufferContextHelper : public ContextHelper {
+ public:
+ FrameBufferContextHelper(FrameBuffer* fb) : mFb(fb) {}
+
+ virtual bool setupContext() override {
+ mIsBound = mFb->bind_locked();
+ return mIsBound;
+ }
+
+ virtual void teardownContext() override {
+ mFb->unbind_locked();
+ mIsBound = false;
+ }
+
+ virtual TextureDraw* getTextureDraw() const override {
+ return mFb->getTextureDraw();
+ }
+
+ virtual bool isBound() const override { return mIsBound; }
+
+ private:
+ FrameBuffer* mFb;
+ bool mIsBound = false;
+};
+
} // namespace
// static std::string getTimeStampString() {
@@ -283,15 +309,6 @@
// will get cleaned when the process exits.
if (m_useSubWindow) {
m_postWorker.reset();
- if (m_displayVk) {
- m_displayVk->unbindFromSurface();
- }
- if (m_displayGl) {
- m_displayGl->unbindFromSurface();
- }
- if (m_compositorGl) {
- m_compositorGl->unbindFromSurface();
- }
removeSubWindow_locked();
}
return;
@@ -310,25 +327,24 @@
}
m_windows.clear();
m_contexts.clear();
-
if (m_eglDisplay != EGL_NO_DISPLAY) {
s_egl.eglMakeCurrent(m_eglDisplay, NULL, NULL, NULL);
-
- m_pbufferSurface.reset();
- if (m_displayVk) {
- m_displayVk->unbindFromSurface();
- }
- if (m_displayGl) {
- m_displayGl->unbindFromSurface();
- }
- if (m_compositorGl) {
- m_compositorGl->unbindFromSurface();
- }
- m_fakeWindowSurface.reset();
if (m_eglContext != EGL_NO_CONTEXT) {
s_egl.eglDestroyContext(m_eglDisplay, m_eglContext);
m_eglContext = EGL_NO_CONTEXT;
}
+ if (m_pbufContext != EGL_NO_CONTEXT) {
+ s_egl.eglDestroyContext(m_eglDisplay, m_pbufContext);
+ m_pbufContext = EGL_NO_CONTEXT;
+ }
+ if (m_pbufSurface != EGL_NO_SURFACE) {
+ s_egl.eglDestroySurface(m_eglDisplay, m_pbufSurface);
+ m_pbufSurface = EGL_NO_SURFACE;
+ }
+ if (m_eglSurface != EGL_NO_SURFACE) {
+ s_egl.eglDestroySurface(m_eglDisplay, m_eglSurface);
+ m_eglSurface = EGL_NO_SURFACE;
+ }
m_eglDisplay = EGL_NO_DISPLAY;
}
@@ -355,6 +371,8 @@
return false;
}
+ std::unique_ptr<RecursiveScopedContextBind> eglColorBufferBind;
+
std::unique_ptr<emugl::RenderDocWithMultipleVkInstances> renderDocMultipleVkInstances = nullptr;
if (!android::base::getEnvironmentVariable("ANDROID_EMU_RENDERDOC").empty()) {
SharedLibrary* renderdocLib = nullptr;
@@ -594,44 +612,38 @@
// on Mac platform when switching binded drawable for a context however
// it is more efficient on other platforms as well.
//
- auto pbufferSurfaceGl = DisplaySurfaceGl::createPbufferSurface(fb->m_eglDisplay,
- fb->m_eglConfig,
- fb->m_eglContext,
- getGlesMaxContextAttribs(),
- /*width=*/1,
- /*height=*/1);
- if (!pbufferSurfaceGl) {
- ERR("Failed to create pbuffer display surface.");
+ fb->m_pbufContext =
+ s_egl.eglCreateContext(fb->m_eglDisplay, fb->m_eglConfig,
+ fb->m_eglContext, getGlesMaxContextAttribs());
+ if (fb->m_pbufContext == EGL_NO_CONTEXT) {
+ ERR("Failed to create Pbuffer Context 0x%x", s_egl.eglGetError());
return false;
}
- fb->m_pbufferSurface = std::make_unique<gfxstream::DisplaySurface>(
- /*width=*/1,
- /*height=*/1,
- std::move(pbufferSurfaceGl));
- auto fakeWindowSurfaceGl = DisplaySurfaceGl::createPbufferSurface(fb->m_eglDisplay,
- fb->m_eglConfig,
- fb->m_eglContext,
- getGlesMaxContextAttribs(),
- fb->m_framebufferWidth,
- fb->m_framebufferHeight);
- if (!fakeWindowSurfaceGl) {
- ERR("Failed to create fake window display surface.");
+ GL_LOG("context creation successful");
+
+ //
+ // create a 1x1 pbuffer surface which will be used for binding
+ // the FB context.
+ // The FB output will go to a subwindow, if one exist.
+ //
+ static const EGLint pbufAttribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE};
+
+ fb->m_pbufSurface = s_egl.eglCreatePbufferSurface(
+ fb->m_eglDisplay, fb->m_eglConfig, pbufAttribs);
+ if (fb->m_pbufSurface == EGL_NO_SURFACE) {
+ ERR("Failed to create pbuf surface for FB 0x%x", s_egl.eglGetError());
return false;
}
- fb->m_fakeWindowSurface = std::make_unique<gfxstream::DisplaySurface>(
- fb->m_framebufferWidth,
- fb->m_framebufferHeight,
- std::move(fakeWindowSurfaceGl));
-
- GL_LOG("Attempting to make pbuffer context and surface current");
- RecursiveScopedContextBind contextBind(fb->getPbufferSurfaceContextHelper());
- if (!contextBind.isOk()) {
- ERR("Failed to make pbuffer context and surface current");
+ GL_LOG("attempting to make context current");
+ // Make the context current
+ eglColorBufferBind = std::make_unique<RecursiveScopedContextBind>(fb->m_colorBufferHelper);
+ if (!eglColorBufferBind->isOk()) {
+ ERR("Failed to make current");
return false;
}
- GL_LOG("Succeeded making pbuffer context and surface current");
+ GL_LOG("context-current successful");
//
// Initilize framebuffer capabilities
@@ -868,9 +880,6 @@
}
}
- fb->m_displayGl = std::make_unique<DisplayGl>();
- fb->m_displayGl->bindToSurface(fb->m_fakeWindowSurface.get());
-
if (fb->m_useVulkanComposition) {
if (!vkEmu->compositorVk) {
ERR("Failed to get CompositorVk from VkEmulation.");
@@ -881,8 +890,6 @@
} else {
GL_LOG("Performing composition using CompositorGl.");
fb->m_compositorGl = std::make_unique<CompositorGl>(fb->m_textureDraw);
- fb->m_compositorGl->bindToSurface(fb->m_fakeWindowSurface.get());
-
fb->m_compositor = fb->m_compositorGl.get();
}
@@ -976,6 +983,7 @@
m_fpsStats(getenv("SHOW_FPS_STATS") != nullptr),
m_perfStats(!android::base::getEnvironmentVariable("SHOW_PERF_STATS").empty()),
m_perfThread(new PerfStatThread(&m_perfStats)),
+ m_colorBufferHelper(new FrameBufferContextHelper(this)),
m_readbackThread(
[this](FrameBuffer::Readback&& readback) { return sendReadbackWorkerCmd(readback); }),
m_refCountPipeEnabled(feature_is_enabled(kFeature_RefCountPipe)),
@@ -1007,6 +1015,7 @@
delete m_textureDraw;
delete m_configs;
+ delete m_colorBufferHelper;
delete m_perfThread;
if (s_theFrameBuffer) {
@@ -1131,17 +1140,34 @@
#endif
if (!m_postThread.isStarted()) {
- if (m_displayGl) {
- m_displayGl->setUseBoundSurfaceContext(!postOnlyOnMainThread);
+ if (postOnlyOnMainThread) {
+ EGLContext prevContext = s_egl.eglGetCurrentContext();
+ EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ);
+ EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW);
+ m_prevContext = prevContext;
+ m_prevReadSurf = prevReadSurf;
+ m_prevDrawSurf = prevDrawSurf;
}
- if (m_compositorGl) {
- m_displayGl->setUseBoundSurfaceContext(!postOnlyOnMainThread);
- }
-
- m_postWorker.reset(new PostWorker(postOnlyOnMainThread,
- m_compositor,
- m_displayGl.get(),
- m_displayVk));
+ m_postWorker.reset(new PostWorker(
+ [this]() {
+ if (m_displayVk) {
+ return true;
+ }
+ if (m_subWin) {
+ if (!bindSubwin_locked()) {
+ return false;
+ }
+ } else {
+ if (!bindFakeWindow_locked()) {
+ return false;
+ }
+ }
+ if (m_compositorGl) {
+ m_compositorGl->bindToWindow();
+ }
+ return true;
+ },
+ postOnlyOnMainThread, m_compositor, m_displayVk));
m_postThread.start();
}
@@ -1324,16 +1350,9 @@
#endif
if (deleteExisting) {
- if (m_displayVk) {
- m_displayVk->unbindFromSurface();
- }
- if (m_displayGl) {
- m_displayGl->unbindFromSurface();
- }
- if (m_compositorGl) {
- m_compositorGl->unbindFromSurface();
- }
+ m_displayVk->unbindFromSurface();
m_displaySurface.reset();
+ // TODO: look into reusing the existing native window when possible.
removeSubWindow_locked();
}
@@ -1371,13 +1390,11 @@
reinterpret_cast<RENDERDOC_WindowHandle>(m_subWin));
}
} else {
- // TODO(Bug: b/233939967): move to EmulationGl->createDisplaySurface().
- auto surfaceGl = DisplaySurfaceGl::createWindowSurface(m_eglDisplay,
- m_eglConfig,
- m_eglContext,
- getGlesMaxContextAttribs(),
- m_subWin);
- if (!surfaceGl) {
+ // create EGLSurface from the generated subwindow
+ m_eglSurface = s_egl.eglCreateWindowSurface(
+ m_eglDisplay, m_eglConfig, m_subWin, NULL);
+
+ if (m_eglSurface == EGL_NO_SURFACE) {
// NOTE: This can typically happen with software-only renderers
// like OSMesa.
destroySubWindow(m_subWin);
@@ -1385,17 +1402,8 @@
} else {
m_px = 0;
m_py = 0;
+
success = true;
- m_displaySurface =
- std::make_unique<gfxstream::DisplaySurface>(m_windowWidth,
- m_windowHeight,
- std::move(surfaceGl));
- if (m_displayGl) {
- m_displayGl->bindToSurface(m_displaySurface.get());
- }
- if (m_compositorGl) {
- m_compositorGl->bindToSurface(m_displaySurface.get());
- }
}
}
}
@@ -1464,9 +1472,11 @@
}
if (success && redrawSubwindow) {
- RecursiveScopedContextBind bind(getPbufferSurfaceContextHelper());
- assert(bind.isOk());
+ bool bindSuccess = bind_locked();
+ assert(bindSuccess);
+ (void)bindSuccess;
s_gles2.glViewport(0, 0, fbw * dpr, fbh * dpr);
+ unbind_locked();
}
mutex.unlock();
@@ -1508,20 +1518,10 @@
bool removed = false;
if (m_subWin) {
s_egl.eglMakeCurrent(m_eglDisplay, NULL, NULL, NULL);
-
- if (m_displayVk) {
- m_displayVk->unbindFromSurface();
- }
- if (m_displayGl) {
- m_displayGl->unbindFromSurface();
- }
- if (m_compositorGl) {
- m_compositorGl->unbindFromSurface();
- }
-
- m_windowSurface.reset();
+ s_egl.eglDestroySurface(m_eglDisplay, m_eglSurface);
destroySubWindow(m_subWin);
+ m_eglSurface = EGL_NO_SURFACE;
m_subWin = (EGLNativeWindowType)0;
removed = true;
}
@@ -1595,8 +1595,7 @@
ColorBufferPtr cb(ColorBuffer::create(getDisplay(), p_width, p_height,
p_internalFormat, p_frameworkFormat,
- handle, getPbufferSurfaceContextHelper(),
- m_textureDraw,
+ handle, m_colorBufferHelper,
m_fastBlitSupported, m_guestUsesAngle));
if (cb.get() != NULL) {
assert(m_colorbuffers.count(handle) == 0);
@@ -1683,7 +1682,7 @@
<< "Buffer already exists with handle " << handle;
}
- BufferPtr buffer(Buffer::create(p_size, handle, getPbufferSurfaceContextHelper()));
+ BufferPtr buffer(Buffer::create(p_size, handle, m_colorBufferHelper));
if (buffer) {
m_buffers[handle] = {std::move(buffer)};
@@ -1839,7 +1838,7 @@
std::vector<HandleType> colorBuffersToCleanup;
AutoLock mutex(m_lock);
- RecursiveScopedContextBind bind(getPbufferSurfaceContextHelper());
+ RecursiveScopedContextBind bind(m_colorBufferHelper);
for (const HandleType winHandle : tinfo->m_windowSet) {
const auto winIt = m_windows.find(winHandle);
if (winIt != m_windows.end()) {
@@ -1911,7 +1910,7 @@
std::vector<HandleType> colorBuffersToCleanUp;
const auto w = m_windows.find(p_surface);
if (w != m_windows.end()) {
- RecursiveScopedContextBind bind(getPbufferSurfaceContextHelper());
+ RecursiveScopedContextBind bind(m_colorBufferHelper);
if (!m_guestManagedColorBufferLifetime) {
if (m_refCountPipeEnabled) {
if (decColorBufferRefCountLocked(w->second.second)) {
@@ -2168,7 +2167,7 @@
std::vector<HandleType> FrameBuffer::cleanupProcGLObjects_locked(uint64_t puid, bool forced) {
std::vector<HandleType> colorBuffersToCleanup;
{
- RecursiveScopedContextBind bind(getPbufferSurfaceContextHelper());
+ RecursiveScopedContextBind bind(m_colorBufferHelper);
// Clean up window surfaces
{
auto procIte = m_procOwnedWindowSurfaces.find(puid);
@@ -2393,7 +2392,7 @@
uint32_t* output) {
FrameworkFormat format = static_cast<FrameworkFormat>(type);
AutoLock mutex(m_lock);
- RecursiveScopedContextBind bind(getPbufferSurfaceContextHelper());
+ RecursiveScopedContextBind bind(m_colorBufferHelper);
for (uint32_t i = 0; i < count; ++i) {
if (format == FRAMEWORK_FORMAT_NV12) {
YUVConverter::createYUVGLTex(GL_TEXTURE0, width, height,
@@ -2415,7 +2414,7 @@
uint32_t count,
uint32_t* textures) {
AutoLock mutex(m_lock);
- RecursiveScopedContextBind bind(getPbufferSurfaceContextHelper());
+ RecursiveScopedContextBind bind(m_colorBufferHelper);
if (type == FRAMEWORK_FORMAT_NV12) {
s_gles2.glDeleteTextures(2 * count, textures);
} else if (type == FRAMEWORK_FORMAT_YUV_420_888) {
@@ -2434,7 +2433,7 @@
void* privData,
void* func) {
AutoLock mutex(m_lock);
- RecursiveScopedContextBind bind(getPbufferSurfaceContextHelper());
+ RecursiveScopedContextBind bind(m_colorBufferHelper);
yuv_updater_t updater = (yuv_updater_t)func;
uint32_t gtextures[3] = {0, 0, 0};
@@ -2771,6 +2770,102 @@
return true;
}
+//
+// The framebuffer lock should be held when calling this function !
+//
+bool FrameBuffer::bind_locked() {
+ EGLContext prevContext = s_egl.eglGetCurrentContext();
+ EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ);
+ EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW);
+
+ if (prevContext != m_pbufContext || prevReadSurf != m_pbufSurface ||
+ prevDrawSurf != m_pbufSurface) {
+ if (!s_egl.eglMakeCurrent(m_eglDisplay, m_pbufSurface, m_pbufSurface,
+ m_pbufContext)) {
+ if (!m_shuttingDown)
+ ERR("eglMakeCurrent failed");
+ return false;
+ }
+ } else {
+ ERR("Nested %s call detected, should never happen\n", __func__);
+ }
+
+ m_prevContext = prevContext;
+ m_prevReadSurf = prevReadSurf;
+ m_prevDrawSurf = prevDrawSurf;
+ return true;
+}
+
+bool FrameBuffer::bindSubwin_locked() {
+ EGLContext prevContext = s_egl.eglGetCurrentContext();
+ EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ);
+ EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW);
+
+ if (prevContext != m_eglContext || prevReadSurf != m_eglSurface ||
+ prevDrawSurf != m_eglSurface) {
+ if (!s_egl.eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface,
+ m_eglContext)) {
+ ERR("eglMakeCurrent failed in binding subwindow!");
+ return false;
+ }
+ }
+
+ //
+ // initialize GL state in eglContext if not yet initilaized
+ //
+ if (!m_eglContextInitialized) {
+ m_eglContextInitialized = true;
+ }
+
+ m_prevContext = prevContext;
+ m_prevReadSurf = prevReadSurf;
+ m_prevDrawSurf = prevDrawSurf;
+ return true;
+}
+
+bool FrameBuffer::bindFakeWindow_locked() {
+ if (m_eglFakeWindowSurface == EGL_NO_SURFACE) {
+ // initialize here
+ m_eglFakeWindowContext = s_egl.eglCreateContext(
+ m_eglDisplay, m_eglConfig, m_eglContext,
+ getGlesMaxContextAttribs());
+
+ static const EGLint kFakeWindowPbufAttribs[] = {
+ EGL_WIDTH, m_framebufferWidth, EGL_HEIGHT,
+ m_framebufferWidth, EGL_NONE,
+ };
+
+ m_eglFakeWindowSurface = s_egl.eglCreatePbufferSurface(
+ m_eglDisplay, m_eglConfig, kFakeWindowPbufAttribs);
+ }
+
+ if (!s_egl.eglMakeCurrent(m_eglDisplay, m_eglFakeWindowSurface,
+ m_eglFakeWindowSurface, m_eglFakeWindowContext)) {
+ ERR("eglMakeCurrent failed in binding fake window!");
+ return false;
+ }
+ return true;
+}
+
+bool FrameBuffer::unbind_locked() {
+ EGLContext curContext = s_egl.eglGetCurrentContext();
+ EGLSurface curReadSurf = s_egl.eglGetCurrentSurface(EGL_READ);
+ EGLSurface curDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW);
+
+ if (m_prevContext != curContext || m_prevReadSurf != curReadSurf ||
+ m_prevDrawSurf != curDrawSurf) {
+ if (!s_egl.eglMakeCurrent(m_eglDisplay, m_prevDrawSurf, m_prevReadSurf,
+ m_prevContext)) {
+ return false;
+ }
+ }
+
+ m_prevContext = EGL_NO_CONTEXT;
+ m_prevReadSurf = EGL_NO_SURFACE;
+ m_prevDrawSurf = EGL_NO_SURFACE;
+ return true;
+}
+
void FrameBuffer::createTrivialContext(HandleType shared,
HandleType* contextOut,
HandleType* surfOut) {
@@ -2800,7 +2895,7 @@
EGL_NONE };
*contextOut = s_egl.eglCreateContext(
- m_eglDisplay, config->getHostEglConfig(), getGlobalEGLContext(), contextAttribs);
+ m_eglDisplay, config->getHostEglConfig(), m_pbufContext, contextAttribs);
const EGLint pbufAttribs[] = {
EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE };
@@ -3173,14 +3268,14 @@
switch (composeDevice->version) {
case 1: {
- RecursiveScopedContextBind scopedBind(getPbufferSurfaceContextHelper());
+ RecursiveScopedContextBind scopedBind(m_colorBufferHelper);
post(composeDevice->targetHandle, false);
break;
}
case 2: {
ComposeDevice_v2* composeDeviceV2 = (ComposeDevice_v2*)buffer;
if (composeDeviceV2->displayId == 0) {
- RecursiveScopedContextBind scopedBind(getPbufferSurfaceContextHelper());
+ RecursiveScopedContextBind scopedBind(m_colorBufferHelper);
post(composeDeviceV2->targetHandle, false);
}
break;
@@ -3246,7 +3341,7 @@
// m_prevDrawSurf
AutoLock mutex(m_lock);
// set up a context because some snapshot commands try using GL
- RecursiveScopedContextBind scopedBind(getPbufferSurfaceContextHelper());
+ RecursiveScopedContextBind scopedBind(m_colorBufferHelper);
// eglPreSaveContext labels all guest context textures to be saved
// (textures created by the host are not saved!)
// eglSaveAllImages labels all EGLImages (both host and guest) to be saved
@@ -3265,6 +3360,7 @@
stream->putFloat(m_dpr);
stream->putBe32(m_useSubWindow);
+ stream->putBe32(m_eglContextInitialized);
stream->putBe32(m_fpsStats);
stream->putBe32(m_statsNumFrames);
@@ -3319,11 +3415,14 @@
s_egl.eglPostSaveContext(m_eglDisplay, ctx.second->getEGLContext(),
stream);
}
- // We need to run the post save step for m_eglContext
+ // We need to run the post save step for m_eglContext and m_pbufContext
// to mark their texture handles dirty
if (m_eglContext != EGL_NO_CONTEXT) {
s_egl.eglPostSaveContext(m_eglDisplay, m_eglContext, stream);
}
+ if (m_pbufContext != EGL_NO_CONTEXT) {
+ s_egl.eglPostSaveContext(m_eglDisplay, m_pbufContext, stream);
+ }
}
}
@@ -3335,7 +3434,7 @@
{
sweepColorBuffersLocked();
- RecursiveScopedContextBind scopedBind(getPbufferSurfaceContextHelper());
+ RecursiveScopedContextBind scopedBind(m_colorBufferHelper);
bool cleanupComplete = false;
{
AutoLock colorBufferMapLock(m_colorBufferMapLock);
@@ -3444,6 +3543,7 @@
// TODO: resize the window
//
m_useSubWindow = stream->getBe32();
+ m_eglContextInitialized = stream->getBe32();
m_fpsStats = stream->getBe32();
m_statsNumFrames = stream->getBe32();
@@ -3462,8 +3562,8 @@
m_guestManagedColorBufferLifetime = stream->getByte();
loadCollection(
stream, &m_colorbuffers, [this, now](Stream* stream) -> ColorBufferMap::value_type {
- ColorBufferPtr cb(ColorBuffer::onLoad(stream, m_eglDisplay, getPbufferSurfaceContextHelper(),
- m_textureDraw, m_fastBlitSupported));
+ ColorBufferPtr cb(ColorBuffer::onLoad(stream, m_eglDisplay, m_colorBufferHelper,
+ m_fastBlitSupported));
const HandleType handle = cb->getHndl();
const unsigned refCount = stream->getBe32();
const bool opened = stream->getByte();
@@ -3497,7 +3597,7 @@
registerTriggerWait();
{
- RecursiveScopedContextBind scopedBind(getPbufferSurfaceContextHelper());
+ RecursiveScopedContextBind scopedBind(m_colorBufferHelper);
AutoLock colorBufferMapLock(m_colorBufferMapLock);
for (auto& it : m_colorbuffers) {
if (it.second.cb) {
@@ -3815,38 +3915,3 @@
}
return colorBufferPtr->getBorrowedImageInfo();
}
-
-EGLSurface FrameBuffer::getWindowSurface() const {
- if (!m_windowSurface) {
- return EGL_NO_SURFACE;
- }
-
- const auto* displaySurfaceGl =
- reinterpret_cast<const DisplaySurfaceGl*>(m_windowSurface->getImpl());
-
- return displaySurfaceGl->getSurface();
-}
-
-EGLContext FrameBuffer::getGlobalEGLContext() const {
- if (!m_pbufferSurface) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
- << "FrameBuffer pbuffer surface not available.";
- }
-
- const auto* displaySurfaceGl =
- reinterpret_cast<const DisplaySurfaceGl*>(m_pbufferSurface->getImpl());
-
- return displaySurfaceGl->getContextForShareContext();
-}
-
-ContextHelper* FrameBuffer::getPbufferSurfaceContextHelper() const {
- if (!m_pbufferSurface) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
- << "FrameBuffer pbuffer surface not available.";
- }
-
- const auto* displaySurfaceGl =
- reinterpret_cast<const DisplaySurfaceGl*>(m_pbufferSurface->getImpl());
-
- return displaySurfaceGl->getContextHelper();
-}
diff --git a/stream-servers/FrameBuffer.h b/stream-servers/FrameBuffer.h
index 1404463..a740177 100644
--- a/stream-servers/FrameBuffer.h
+++ b/stream-servers/FrameBuffer.h
@@ -33,6 +33,7 @@
#include "Compositor.h"
#include "Display.h"
#include "DisplaySurface.h"
+#include "DisplayVk.h"
#include "Hwc2.h"
#include "PostCommands.h"
#include "PostWorker.h"
@@ -48,7 +49,6 @@
#include "aemu/base/threads/Thread.h"
#include "aemu/base/threads/WorkerThread.h"
#include "gl/CompositorGl.h"
-#include "gl/DisplaySurfaceGl.h"
#include "gl/EmulatedEglConfig.h"
#include "gl/GLESVersionDetector.h"
#include "gl/RenderContext.h"
@@ -64,8 +64,6 @@
using emugl::HealthMonitor;
using emugl::MetricsLogger;
-class DisplayVk;
-
struct ColorBufferRef {
ColorBufferPtr cb;
uint32_t refcount; // number of client-side references
@@ -464,10 +462,9 @@
// Return the host EGLDisplay used by this instance.
EGLDisplay getDisplay() const { return m_eglDisplay; }
- EGLSurface getWindowSurface() const;
+ EGLSurface getWindowSurface() const { return m_eglSurface; }
EGLContext getContext() const { return m_eglContext; }
EGLConfig getConfig() const { return m_eglConfig; }
- ContextHelper* getPbufferSurfaceContextHelper() const;
// Change the rotation of the displayed GPU sub-window.
void setDisplayRotation(float zRot) {
@@ -507,6 +504,10 @@
// https://www.khronos.org/registry/egl/extensions/KHR/EGL_KHR_image_base.txt
EGLBoolean destroyClientImage(HandleType image);
+ // Used internally.
+ bool bind_locked();
+ bool unbind_locked();
+
void lockContextStructureRead() { m_contextStructureLock.lockRead(); }
void unlockContextStructureRead() { m_contextStructureLock.unlockRead(); }
@@ -572,6 +573,7 @@
int displayId, int desiredWidth, int desiredHeight,
int desiredRotation);
void onLastColorBufferRef(uint32_t handle);
+ ContextHelper* getColorBufferHelper() { return m_colorBufferHelper; }
ColorBufferPtr findColorBuffer(HandleType p_colorbuffer);
BufferPtr findBuffer(HandleType p_buffer);
@@ -610,7 +612,7 @@
static const uint32_t s_invalidIdMultiDisplay = 0xFFFFFFAB;
static const uint32_t s_maxNumMultiDisplay = 11;
- EGLContext getGlobalEGLContext() const;
+ EGLContext getGlobalEGLContext() { return m_pbufContext; }
HandleType getLastPostedColorBuffer() { return m_lastPostedColorBuffer; }
void waitForGpu(uint64_t eglsync);
void waitForGpuVulkan(uint64_t deviceHandle, uint64_t fenceHandle);
@@ -640,6 +642,8 @@
// the object handle maps.
HandleType genHandle_locked();
+ bool bindSubwin_locked();
+ bool bindFakeWindow_locked();
bool removeSubWindow_locked();
// Returns the set of ColorBuffers destroyed (for further cleanup)
std::vector<HandleType> cleanupProcGLObjects_locked(uint64_t puid,
@@ -683,6 +687,7 @@
float m_dpr = 0;
bool m_useSubWindow = false;
+ bool m_eglContextInitialized = false;
bool m_fpsStats = false;
bool m_perfStats = false;
@@ -720,16 +725,19 @@
using ColorBufferDelayedClose = std::vector<ColorBufferCloseInfo>;
ColorBufferDelayedClose m_colorBufferDelayedCloseList;
+ ContextHelper* m_colorBufferHelper = nullptr;
+
+ EGLSurface m_eglSurface = EGL_NO_SURFACE;
EGLContext m_eglContext = EGL_NO_CONTEXT;
+ EGLSurface m_pbufSurface = EGL_NO_SURFACE;
+ EGLContext m_pbufContext = EGL_NO_CONTEXT;
- // TODO(b/233939967): move to EmulationGl
- // Used for ColorBuffer ops.
- std::unique_ptr<gfxstream::DisplaySurface> m_pbufferSurface;
- // TODO(b/233939967): move to EmulationGl
- // Used for Composition and Display ops.
- std::unique_ptr<gfxstream::DisplaySurface> m_windowSurface;
- std::unique_ptr<gfxstream::DisplaySurface> m_fakeWindowSurface;
+ EGLSurface m_eglFakeWindowSurface = EGL_NO_SURFACE;
+ EGLContext m_eglFakeWindowContext = EGL_NO_CONTEXT;
+ EGLContext m_prevContext = EGL_NO_CONTEXT;
+ EGLSurface m_prevReadSurf = EGL_NO_SURFACE;
+ EGLSurface m_prevDrawSurf = EGL_NO_SURFACE;
EGLNativeWindowType m_subWin = {};
TextureDraw* m_textureDraw = nullptr;
EGLConfig m_eglConfig = nullptr;
@@ -833,8 +841,6 @@
std::unique_ptr<CompositorGl> m_compositorGl;
bool m_useVulkanComposition = false;
- // TODO(b/233939967): move to EmulationGl.
- std::unique_ptr<DisplayGl> m_displayGl;
// The implementation for Vulkan native swapchain. Only initialized when useVulkan is set when
// calling FrameBuffer::initialize(). DisplayVk is actually owned by VkEmulation.
DisplayVk *m_displayVk = nullptr;
diff --git a/stream-servers/PostWorker.cpp b/stream-servers/PostWorker.cpp
index 2147fc1..c145984 100644
--- a/stream-servers/PostWorker.cpp
+++ b/stream-servers/PostWorker.cpp
@@ -20,15 +20,17 @@
#include <chrono>
#include "ColorBuffer.h"
+#include "CompositorGl.h"
#include "Debug.h"
#include "FrameBuffer.h"
+#include "OpenGLESDispatch/DispatchTables.h"
+#include "OpenGLESDispatch/EGLDispatch.h"
+#include "OpenGLESDispatch/GLESv2Dispatch.h"
#include "RenderThreadInfo.h"
#include "aemu/base/Tracing.h"
-#include "gl/DisplayGl.h"
#include "host-common/GfxstreamFatalError.h"
#include "host-common/logging.h"
#include "host-common/misc.h"
-#include "vulkan/DisplayVk.h"
#include "vulkan/VkCommonOperations.h"
using emugl::ABORT_REASON_OTHER;
@@ -55,172 +57,137 @@
(void)wait;
}
-namespace {
-
-hwc_transform_t getTransformFromRotation(int rotation) {
- switch (static_cast<int>(rotation / 90)) {
- case 1:
- return HWC_TRANSFORM_ROT_270;
- case 2:
- return HWC_TRANSFORM_ROT_180;
- case 3:
- return HWC_TRANSFORM_ROT_90;
- default:
- return HWC_TRANSFORM_NONE;
- }
-}
-
-} // namespace
-
-PostWorker::PostWorker(bool mainThreadPostingOnly, Compositor* compositor,
- DisplayGl* displayGl, DisplayVk* displayVk)
+PostWorker::PostWorker(PostWorker::BindSubwinCallback&& cb, bool mainThreadPostingOnly,
+ Compositor* compositor, DisplayVk* displayVk)
: mFb(FrameBuffer::getFB()),
+ mBindSubwin(cb),
m_mainThreadPostingOnly(mainThreadPostingOnly),
m_runOnUiThread(m_mainThreadPostingOnly ? emugl::get_emugl_window_operations().runOnUiThread
: sDefaultRunOnUiThread),
m_compositor(compositor),
- m_displayGl(displayGl),
m_displayVk(displayVk) {}
+void PostWorker::fillMultiDisplayPostStruct(ComposeLayer* l,
+ hwc_rect_t displayArea,
+ hwc_frect_t cropArea,
+ hwc_transform_t transform) {
+ l->composeMode = HWC2_COMPOSITION_DEVICE;
+ l->blendMode = HWC2_BLEND_MODE_NONE;
+ l->transform = transform;
+ l->alpha = 1.0;
+ l->displayFrame = displayArea;
+ l->crop = cropArea;
+}
+
std::shared_future<void> PostWorker::postImpl(ColorBuffer* cb) {
+ std::shared_future<void> completedFuture =
+ std::async(std::launch::deferred, [] {}).share();
+ completedFuture.wait();
+ // bind the subwindow eglSurface
+ if (!m_mainThreadPostingOnly && m_needsToRebindWindow) {
+ m_needsToRebindWindow = !mBindSubwin();
+ if (m_needsToRebindWindow) {
+ // Do not proceed if fail to bind to the window.
+ return completedFuture;
+ }
+ }
+
if (m_displayVk) {
const auto imageInfo = mFb->borrowColorBufferForDisplay(cb->getHndl());
return m_displayVk->post(imageInfo.get());
}
- if (!m_displayGl) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
- << "PostWorker missing DisplayGl.";
- }
+ float dpr = mFb->getDpr();
+ int windowWidth = mFb->windowWidth();
+ int windowHeight = mFb->windowHeight();
+ float px = mFb->getPx();
+ float py = mFb->getPy();
+ int zRot = mFb->getZrot();
+ hwc_transform_t rotation = (hwc_transform_t)0;
- DisplayGl::Post post = {};
+ // Find the x and y values at the origin when "fully scrolled."
+ // Multiply by 2 because the texture goes from -1 to 1, not 0 to 1.
+ // Multiply the windowing coordinates by DPR because they ignore
+ // DPR, but the viewport includes DPR.
+ float fx = 2.f * (m_viewportWidth - windowWidth * dpr) / (float)m_viewportWidth;
+ float fy = 2.f * (m_viewportHeight - windowHeight * dpr) / (float)m_viewportHeight;
- ComposeLayer postLayerOptions = {
- .composeMode = HWC2_COMPOSITION_DEVICE,
- .blendMode = HWC2_BLEND_MODE_NONE,
- .transform = HWC_TRANSFORM_NONE,
- };
+ // finally, compute translation values
+ float dx = px * fx;
+ float dy = py * fy;
- const auto& multiDisplay = emugl::get_emugl_multi_display_operations();
- if (multiDisplay.isMultiDisplayEnabled()) {
- uint32_t combinedDisplayW = 0;
- uint32_t combinedDisplayH = 0;
- multiDisplay.getCombinedDisplaySize(&combinedDisplayW, &combinedDisplayH);
-
- post.frameWidth = combinedDisplayW;
- post.frameHeight = combinedDisplayH;
-
- int32_t previousDisplayId = -1;
- uint32_t currentDisplayId;
- int32_t currentDisplayOffsetX;
- int32_t currentDisplayOffsetY;
- uint32_t currentDisplayW;
- uint32_t currentDisplayH;
- uint32_t currentDisplayColorBufferHandle;
- while (multiDisplay.getNextMultiDisplay(previousDisplayId,
- ¤tDisplayId,
- ¤tDisplayOffsetX,
- ¤tDisplayOffsetY,
- ¤tDisplayW,
- ¤tDisplayH,
- /*dpi=*/nullptr,
- /*flags=*/nullptr,
- ¤tDisplayColorBufferHandle)) {
- previousDisplayId = currentDisplayId;
-
- if (currentDisplayW == 0 ||
- currentDisplayH == 0 ||
- currentDisplayColorBufferHandle == 0) {
+ if (emugl::get_emugl_multi_display_operations().isMultiDisplayEnabled()) {
+ uint32_t combinedW, combinedH;
+ emugl::get_emugl_multi_display_operations().getCombinedDisplaySize(&combinedW, &combinedH);
+ mFb->getTextureDraw()->prepareForDrawLayer();
+ int32_t start_id = -1, x, y;
+ uint32_t id, w, h, c;
+ while(emugl::get_emugl_multi_display_operations().getNextMultiDisplay(start_id, &id,
+ &x, &y, &w, &h,
+ nullptr, nullptr,
+ &c)) {
+ if ((id != 0) && (w == 0 || h == 0 || c == 0)) {
+ start_id = id;
continue;
}
-
- ColorBuffer* cb = mFb->findColorBuffer(currentDisplayColorBufferHandle).get();
- if (!cb) {
+ ColorBuffer* multiDisplayCb = id == 0 ? cb : mFb->findColorBuffer(c).get();
+ if (multiDisplayCb == nullptr) {
+ start_id = id;
continue;
}
-
- postLayerOptions.displayFrame = {
- .left = static_cast<int>(currentDisplayOffsetX),
- .top = static_cast<int>(currentDisplayOffsetY),
- .right = static_cast<int>(currentDisplayOffsetX + currentDisplayW),
- .bottom = static_cast<int>(currentDisplayOffsetY + currentDisplayH),
- };
- postLayerOptions.crop = {
- .left = 0.0f,
- .top = static_cast<float>(cb->getHeight()),
- .right = static_cast<float>(cb->getWidth()),
- .bottom = 0.0f,
- };
-
- post.layers.push_back(DisplayGl::PostLayer{
- .colorBuffer = cb,
- .layerOptions = postLayerOptions,
- });
+ ComposeLayer l;
+ hwc_rect_t displayArea = { .left = (int)x,
+ .top = (int)y,
+ .right = (int)(x + w),
+ .bottom = (int)(y + h) };
+ hwc_frect_t cropArea = { .left = 0.0,
+ .top = (float)multiDisplayCb->getHeight(),
+ .right = (float)multiDisplayCb->getWidth(),
+ .bottom = 0.0 };
+ fillMultiDisplayPostStruct(&l, displayArea, cropArea, rotation);
+ multiDisplayCb->postLayer(l, combinedW, combinedH);
+ start_id = id;
}
- } else if (emugl::get_emugl_window_operations().isFolded()) {
- const float dpr = mFb->getDpr();
+ mFb->getTextureDraw()->cleanupForDrawLayer();
+ }
+ else if (emugl::get_emugl_window_operations().isFolded()) {
+ mFb->getTextureDraw()->prepareForDrawLayer();
+ ComposeLayer l;
+ int x, y, w, h;
+ emugl::get_emugl_window_operations().getFoldedArea(&x, &y, &w, &h);
+ hwc_rect_t displayArea = { .left = 0,
+ .top = 0,
+ .right = windowWidth,
+ .bottom = windowHeight };
+ hwc_frect_t cropArea = { .left = (float)x,
+ .top = (float)(y + h),
+ .right = (float)(x + w),
+ .bottom = (float)y };
+ switch ((int)zRot/90) {
+ case 1:
+ rotation = HWC_TRANSFORM_ROT_270;
+ break;
+ case 2:
+ rotation = HWC_TRANSFORM_ROT_180;
+ break;
+ case 3:
+ rotation = HWC_TRANSFORM_ROT_90;
+ break;
+ default: ;
+ }
- post.frameWidth = m_viewportWidth;
- post.frameHeight = m_viewportHeight;
-
- int displayOffsetX;
- int displayOffsetY;
- int displayW;
- int displayH;
- emugl::get_emugl_window_operations().getFoldedArea(&displayOffsetX,
- &displayOffsetY,
- &displayW,
- &displayH);
-
- postLayerOptions.displayFrame = {
- .left = 0,
- .top = 0,
- .right = mFb->windowWidth(),
- .bottom = mFb->windowHeight(),
- };
- postLayerOptions.crop = {
- .left = static_cast<float>(displayOffsetX),
- .top = static_cast<float>(displayOffsetY + displayH),
- .right = static_cast<float>(displayOffsetX + displayW),
- .bottom = static_cast<float>(displayOffsetY),
- };
- postLayerOptions.transform = getTransformFromRotation(mFb->getZrot());
-
- post.layers.push_back(DisplayGl::PostLayer{
- .colorBuffer = cb,
- .layerOptions = postLayerOptions,
- });
- } else {
- float dpr = mFb->getDpr();
- int windowWidth = mFb->windowWidth();
- int windowHeight = mFb->windowHeight();
- float px = mFb->getPx();
- float py = mFb->getPy();
- int zRot = mFb->getZrot();
- hwc_transform_t rotation = (hwc_transform_t)0;
-
- // Find the x and y values at the origin when "fully scrolled."
- // Multiply by 2 because the texture goes from -1 to 1, not 0 to 1.
- // Multiply the windowing coordinates by DPR because they ignore
- // DPR, but the viewport includes DPR.
- float fx = 2.f * (m_viewportWidth - windowWidth * dpr) / (float)m_viewportWidth;
- float fy = 2.f * (m_viewportHeight - windowHeight * dpr) / (float)m_viewportHeight;
-
- // finally, compute translation values
- float dx = px * fx;
- float dy = py * fy;
-
- post.layers.push_back(DisplayGl::PostLayer{
- .colorBuffer = cb,
- .overlayOptions = DisplayGl::PostLayer::OverlayOptions{
- .rotation = static_cast<float>(zRot),
- .dx = dx,
- .dy = dy,
- },
- });
+ fillMultiDisplayPostStruct(&l, displayArea, cropArea, rotation);
+ cb->postLayer(l, m_viewportWidth/dpr, m_viewportHeight/dpr);
+ mFb->getTextureDraw()->cleanupForDrawLayer();
+ }
+ else {
+ // render the color buffer to the window and apply the overlay
+ GLuint tex = cb->getViewportScaledTexture();
+ cb->postWithOverlay(tex, zRot, dx, dy);
}
- return m_displayGl->post(post);
+ s_egl.eglSwapBuffers(mFb->getDisplay(), mFb->getWindowSurface());
+ return completedFuture;
}
// Called whenever the subwindow needs a refresh (FrameBuffer::setupSubWindow).
@@ -228,19 +195,27 @@
// when the refresh is a display change, for instance)
// and resets the posting viewport.
void PostWorker::viewportImpl(int width, int height) {
+ if (!m_mainThreadPostingOnly) {
+ // For GLES, we rebind the subwindow eglSurface unconditionally: this
+ // could be from a display change, but we want to avoid binding
+ // VkSurfaceKHR too frequently, because that's too expensive.
+ if (!m_displayVk || m_needsToRebindWindow) {
+ m_needsToRebindWindow = !mBindSubwin();
+ if (m_needsToRebindWindow) {
+ // Do not proceed if fail to bind to the window.
+ return;
+ }
+ }
+ }
+
if (m_displayVk) {
return;
}
- const float dpr = mFb->getDpr();
+ float dpr = mFb->getDpr();
m_viewportWidth = width * dpr;
m_viewportHeight = height * dpr;
-
- if (!m_displayGl) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
- << "PostWorker missing DisplayGl.";
- }
- m_displayGl->viewport(m_viewportWidth, m_viewportHeight);
+ s_gles2.glViewport(0, 0, m_viewportWidth, m_viewportHeight);
}
// Called when the subwindow refreshes, but there is no
@@ -252,12 +227,11 @@
GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
<< "PostWorker with Vulkan doesn't support clear";
}
-
- if (!m_displayGl) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
- << "PostWorker missing DisplayGl.";
- }
- m_displayGl->clear();
+#ifndef __linux__
+ s_gles2.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
+ GL_STENCIL_BUFFER_BIT);
+ s_egl.eglSwapBuffers(mFb->getDisplay(), mFb->getWindowSurface());
+#endif
}
std::shared_future<void> PostWorker::composeImpl(const FlatComposeRequest& composeRequest) {
@@ -265,6 +239,19 @@
ERR("The last composition on the target buffer hasn't completed.");
}
+ std::shared_future<void> completedFuture =
+ std::async(std::launch::deferred, [] {}).share();
+ completedFuture.wait();
+
+ // bind the subwindow eglSurface
+ if (!m_mainThreadPostingOnly && m_needsToRebindWindow) {
+ m_needsToRebindWindow = !mBindSubwin();
+ if (m_needsToRebindWindow) {
+ // Do not proceed if fail to bind to the window.
+ return completedFuture;
+ }
+ }
+
Compositor::CompositionRequest compositorRequest = {};
compositorRequest.target = mFb->borrowColorBufferForComposition(composeRequest.targetHandle,
/*colorBufferIsTarget=*/true);
@@ -312,7 +299,12 @@
}));
}
-PostWorker::~PostWorker() {}
+PostWorker::~PostWorker() {
+ if (mFb->getDisplay() != EGL_NO_DISPLAY) {
+ s_egl.eglMakeCurrent(mFb->getDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE,
+ EGL_NO_CONTEXT);
+ }
+}
void PostWorker::post(ColorBuffer* cb, std::unique_ptr<Post::CompletionCallback> postCallback) {
auto packagedPostCallback = std::shared_ptr<Post::CompletionCallback>(std::move(postCallback));
diff --git a/stream-servers/PostWorker.h b/stream-servers/PostWorker.h
index af5ab76..aa68864 100644
--- a/stream-servers/PostWorker.h
+++ b/stream-servers/PostWorker.h
@@ -15,32 +15,35 @@
*/
#pragma once
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+#include <GLES3/gl3.h>
+#include <vulkan/vulkan.h>
+
#include <functional>
#include <future>
#include <optional>
-#include <unordered_map>
#include <vector>
#include "Compositor.h"
-#include "ContextHelper.h"
+#include "DisplayVk.h"
#include "Hwc2.h"
#include "PostCommands.h"
#include "aemu/base/Compiler.h"
#include "aemu/base/synchronization/Lock.h"
#include "aemu/base/synchronization/MessageChannel.h"
-#include "gl/DisplayGl.h"
#include "host-common/window_agent.h"
class ColorBuffer;
-class DisplayGl;
-class DisplayVk;
class FrameBuffer;
struct RenderThreadInfo;
class PostWorker {
public:
- PostWorker(bool mainThreadPostingOnly, Compositor* compositor,
- DisplayGl* displayGl, DisplayVk* displayVk);
+ using BindSubwinCallback = std::function<bool(void)>;
+
+ PostWorker(BindSubwinCallback&& cb, bool mainThreadPostingOnly, Compositor* compositor,
+ DisplayVk* display);
~PostWorker();
// post: posts the next color buffer.
@@ -77,6 +80,10 @@
std::shared_future<void> composeImpl(const FlatComposeRequest& composeRequest);
void clearImpl();
+ void fillMultiDisplayPostStruct(ComposeLayer* l, hwc_rect_t displayArea,
+ hwc_frect_t cropArea,
+ hwc_transform_t transform);
+
// If m_mainThreadPostingOnly is true, schedule the task to UI thread by
// using m_runOnUiThread. Otherwise, execute the task on the current thread.
void runTask(std::packaged_task<void()>);
@@ -88,15 +95,15 @@
Compositor* m_compositor = nullptr;
+ std::function<bool(void)> mBindSubwin;
+
+ bool m_needsToRebindWindow = true;
int m_viewportWidth = 0;
int m_viewportHeight = 0;
bool m_mainThreadPostingOnly = false;
UiThreadRunner m_runOnUiThread = 0;
- // TODO(b/233939967): conslidate DisplayGl and DisplayVk into
- // `Display* const m_display`.
- DisplayGl* const m_displayGl;
// The implementation for Vulkan native swapchain. Only initialized when
// useVulkan is set when calling FrameBuffer::initialize(). PostWorker
// doesn't take the ownership of this DisplayVk object.
diff --git a/stream-servers/gl/Android.bp b/stream-servers/gl/Android.bp
index 941152c..9771e96 100644
--- a/stream-servers/gl/Android.bp
+++ b/stream-servers/gl/Android.bp
@@ -13,8 +13,6 @@
defaults: [ "gfxstream_defaults" ],
srcs: [
"CompositorGl.cpp",
- "DisplayGl.cpp",
- "DisplaySurfaceGl.cpp",
"EmulatedEglConfig.cpp",
"GLESVersionDetector.cpp",
"RenderContext.cpp",
diff --git a/stream-servers/gl/CMakeLists.txt b/stream-servers/gl/CMakeLists.txt
index 8043164..822d61d 100644
--- a/stream-servers/gl/CMakeLists.txt
+++ b/stream-servers/gl/CMakeLists.txt
@@ -10,8 +10,6 @@
add_library(gfxstream-gl-server
CompositorGl.cpp
- DisplayGl.cpp
- DisplaySurfaceGl.cpp
EmulatedEglConfig.cpp
GLESVersionDetector.cpp
RenderContext.cpp
diff --git a/stream-servers/gl/CompositorGl.cpp b/stream-servers/gl/CompositorGl.cpp
index f0e0fd5..df2da14 100644
--- a/stream-servers/gl/CompositorGl.cpp
+++ b/stream-servers/gl/CompositorGl.cpp
@@ -16,7 +16,6 @@
#include "BorrowedImageGl.h"
#include "Debug.h"
-#include "DisplaySurfaceGl.h"
#include "OpenGLESDispatch/DispatchTables.h"
#include "TextureDraw.h"
#include "host-common/GfxstreamFatalError.h"
@@ -35,68 +34,27 @@
return nullptr;
}
-std::shared_future<void> getCompletedFuture() {
- std::shared_future<void> completedFuture = std::async(std::launch::deferred, [] {}).share();
- completedFuture.wait();
- return completedFuture;
-}
-
} // namespace
CompositorGl::CompositorGl(TextureDraw* textureDraw) : m_textureDraw(textureDraw) {}
-CompositorGl::~CompositorGl() {}
-
-void CompositorGl::bindToSurfaceImpl(gfxstream::DisplaySurface* surface) {
- const auto* surfaceGl = static_cast<const DisplaySurfaceGl*>(surface->getImpl());
-
- std::optional<RecursiveScopedContextBind> contextBind;
- if (mUseBoundSurfaceContext) {
- contextBind.emplace(surfaceGl->getContextHelper());
- if (!contextBind->isOk()) {
- return;
- }
+CompositorGl::~CompositorGl() {
+ if (m_composeFbo) {
+ s_gles2.glDeleteFramebuffers(1, &m_composeFbo);
}
+}
+void CompositorGl::bindToWindow() {
+ if (m_composeFbo) {
+ s_gles2.glDeleteFramebuffers(1, &m_composeFbo);
+ }
s_gles2.glGenFramebuffers(1, &m_composeFbo);
}
-void CompositorGl::unbindFromSurfaceImpl() {
- const auto* surface = getBoundSurface();
- if (!surface) {
- return;
- }
- const auto* surfaceGl = static_cast<const DisplaySurfaceGl*>(surface->getImpl());
-
- std::optional<RecursiveScopedContextBind> contextBind;
- if (mUseBoundSurfaceContext) {
- contextBind.emplace(surfaceGl->getContextHelper());
- if (!contextBind->isOk()) {
- return;
- }
- }
-
- if (m_composeFbo) {
- s_gles2.glDeleteFramebuffers(1, &m_composeFbo);
- m_composeFbo = 0;
- }
-}
-
Compositor::CompositionFinishedWaitable CompositorGl::compose(
- const CompositionRequest& composeRequest) {
- const auto* surface = getBoundSurface();
- if (!surface) {
- return getCompletedFuture();
- }
- const auto* surfaceGl = static_cast<const DisplaySurfaceGl*>(surface->getImpl());
-
- std::optional<RecursiveScopedContextBind> contextBind;
- if (mUseBoundSurfaceContext) {
- contextBind.emplace(surfaceGl->getContextHelper());
- if (!contextBind->isOk()) {
- return getCompletedFuture();
- }
- }
+ const CompositionRequest& composeRequest) {
+ std::shared_future<void> completedFuture = std::async(std::launch::deferred, [] {}).share();
+ completedFuture.wait();
const auto* targetImage = getInfoOrAbort(composeRequest.target);
const uint32_t targetWidth = targetImage->width;
@@ -139,5 +97,5 @@
// complete but is currently only returning a future when all CPU work is completed.
// In the future, CompositionFinishedWaitable should be replaced with something that
// passes along a GL fence or VK fence.
- return getCompletedFuture();
+ return completedFuture;
}
diff --git a/stream-servers/gl/CompositorGl.h b/stream-servers/gl/CompositorGl.h
index 62b59fd..526e200 100644
--- a/stream-servers/gl/CompositorGl.h
+++ b/stream-servers/gl/CompositorGl.h
@@ -14,36 +14,25 @@
#pragma once
-#include <atomic>
-
#include <EGL/egl.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <GLES3/gl3.h>
#include "Compositor.h"
-#include "DisplaySurfaceUser.h"
#include "TextureDraw.h"
-class CompositorGl : public Compositor, public gfxstream::DisplaySurfaceUser {
+class CompositorGl : public Compositor {
public:
CompositorGl(TextureDraw* textureDraw);
virtual ~CompositorGl();
- // If false, this display will use the existing bound context when performing compositions.
- void setUseBoundSurfaceContext(bool use) { mUseBoundSurfaceContext = use; }
+ void bindToWindow();
CompositionFinishedWaitable compose(const CompositionRequest& compositionRequest) override;
- protected:
- void bindToSurfaceImpl(gfxstream::DisplaySurface* surface) override;
- void unbindFromSurfaceImpl() override;
-
private:
GLuint m_composeFbo = 0;
-
// Owned by FrameBuffer.
TextureDraw* m_textureDraw = nullptr;
-
- std::atomic_bool mUseBoundSurfaceContext{true};
};
diff --git a/stream-servers/gl/DisplayGl.cpp b/stream-servers/gl/DisplayGl.cpp
deleted file mode 100644
index c9541e1..0000000
--- a/stream-servers/gl/DisplayGl.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-// 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"
-
-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());
-
- std::optional<RecursiveScopedContextBind> contextBind;
- if (mUseBoundSurfaceContext) {
- contextBind.emplace(surfaceGl->getContextHelper());
- if (!contextBind->isOk()) {
- return getCompletedFuture();
- }
- }
-
- for (const PostLayer& layer : post.layers) {
- if (layer.layerOptions) {
- layer.colorBuffer->postLayer(*layer.layerOptions,
- post.frameWidth,
- post.frameHeight);
- } else if (layer.overlayOptions) {
- layer.colorBuffer->postWithOverlay(layer.colorBuffer->getViewportScaledTexture(),
- layer.overlayOptions->rotation,
- layer.overlayOptions->dx,
- layer.overlayOptions->dy);
- }
- }
-
- s_egl.eglSwapBuffers(surfaceGl->mDisplay, surfaceGl->mSurface);
-
- return getCompletedFuture();
-}
-
-void DisplayGl::viewport(int width, int height) {
- mViewportWidth = width;
- mViewportHeight = height;
-
- const auto* surface = getBoundSurface();
- if (!surface) {
- return;
- }
-
- std::optional<RecursiveScopedContextBind> contextBind;
- if (mUseBoundSurfaceContext) {
- const auto* surfaceGl = static_cast<const DisplaySurfaceGl*>(surface->getImpl());
- contextBind.emplace(surfaceGl->getContextHelper());
- if (!contextBind->isOk()) {
- return;
- }
- }
-
- 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());
-
- std::optional<RecursiveScopedContextBind> contextBind;
- if (mUseBoundSurfaceContext) {
- contextBind.emplace(surfaceGl->getContextHelper());
- if (!contextBind->isOk()) {
- return;
- }
- }
-
-#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
-}
diff --git a/stream-servers/gl/DisplayGl.h b/stream-servers/gl/DisplayGl.h
deleted file mode 100644
index a59d036..0000000
--- a/stream-servers/gl/DisplayGl.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// 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.
-
-#pragma once
-
-#include <atomic>
-#include <future>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-#include "ColorBuffer.h"
-#include "Display.h"
-#include "Hwc2.h"
-
-class DisplayGl : public gfxstream::Display {
- public:
- DisplayGl() {}
- ~DisplayGl() {}
-
- // If false, this display will use the existing bound context when
- // performing display ops.
- void setUseBoundSurfaceContext(bool use) { mUseBoundSurfaceContext = use; }
-
- struct PostLayer {
- ColorBuffer* colorBuffer = nullptr;
-
- std::optional<ComposeLayer> layerOptions;
-
- // TODO: This should probably be removed and TextureDraw should
- // only use drawLayer() but this is currently needed to support
- // existing draw paths without depending on FrameBuffer directly.
- struct OverlayOptions {
- float rotation;
- float dx;
- float dy;
- };
- std::optional<OverlayOptions> overlayOptions;
- };
-
- // TODO(b/233939967): move to generic Display.
- struct Post {
- uint32_t frameWidth = 0;
- uint32_t frameHeight = 0;
- std::vector<PostLayer> layers;
- };
-
- std::shared_future<void> post(const Post& request);
-
- void viewport(int width, int height);
-
- void clear();
-
- protected:
- void bindToSurfaceImpl(gfxstream::DisplaySurface* surface) override {}
- void unbindFromSurfaceImpl() override {}
-
- private:
- int mViewportWidth = 0;
- int mViewportHeight = 0;
-
- std::atomic_bool mUseBoundSurfaceContext{true};
-};
\ No newline at end of file
diff --git a/stream-servers/gl/DisplaySurfaceGl.cpp b/stream-servers/gl/DisplaySurfaceGl.cpp
deleted file mode 100644
index 70b0695..0000000
--- a/stream-servers/gl/DisplaySurfaceGl.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-// 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 "DisplaySurfaceGl.h"
-
-#include "OpenGLESDispatch/DispatchTables.h"
-#include "OpenGLESDispatch/EGLDispatch.h"
-#include "host-common/GfxstreamFatalError.h"
-#include "host-common/logging.h"
-
-namespace {
-
-using emugl::ABORT_REASON_OTHER;
-using emugl::FatalError;
-
-class DisplaySurfaceGlContextHelper : public ContextHelper {
- public:
- DisplaySurfaceGlContextHelper(EGLDisplay display,
- EGLSurface surface,
- EGLContext context)
- : mDisplay(display),
- mSurface(surface),
- mContext(context) {
- if (mDisplay == EGL_NO_DISPLAY) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
- << "DisplaySurfaceGlContextHelper created with no display?";
- }
- if (mSurface == EGL_NO_SURFACE) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
- << "DisplaySurfaceGlContextHelper created with no surface?";
- }
- if (mContext == EGL_NO_CONTEXT) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
- << "DisplaySurfaceGlContextHelper created with no context?";
- }
- }
-
- bool setupContext() override {
- EGLContext currentContext = s_egl.eglGetCurrentContext();
- EGLSurface currentDrawSurface = s_egl.eglGetCurrentSurface(EGL_DRAW);
- EGLSurface currentReadSurface = s_egl.eglGetCurrentSurface(EGL_READ);
-
- if (currentContext != mContext ||
- currentDrawSurface != mSurface ||
- currentReadSurface != mSurface) {
- if (!s_egl.eglMakeCurrent(mDisplay, mSurface, mSurface, mContext)) {
- ERR("Failed to make display surface context current: %d", s_egl.eglGetError());
- return false;
- }
- }
-
- mPreviousContext = currentContext;
- mPreviousDrawSurface = currentDrawSurface;
- mPreviousReadSurface = currentReadSurface;
-
- mIsBound = true;
-
- return mIsBound;
- }
-
- void teardownContext() override {
- EGLContext currentContext = s_egl.eglGetCurrentContext();
- EGLSurface currentDrawSurface = s_egl.eglGetCurrentSurface(EGL_DRAW);
- EGLSurface currentReadSurface = s_egl.eglGetCurrentSurface(EGL_READ);
-
- if (currentContext != mPreviousContext ||
- currentDrawSurface != mPreviousDrawSurface ||
- currentReadSurface != mPreviousReadSurface) {
- if (!s_egl.eglMakeCurrent(mDisplay,
- mPreviousDrawSurface,
- mPreviousReadSurface,
- mPreviousContext)) {
- ERR("Failed to make restore previous context: %d", s_egl.eglGetError());
- return;
- }
- }
-
- mPreviousContext = EGL_NO_CONTEXT;
- mPreviousDrawSurface = EGL_NO_SURFACE;
- mPreviousReadSurface = EGL_NO_SURFACE;
- mIsBound = false;
- }
-
- bool isBound() const override { return mIsBound; }
-
- private:
- EGLDisplay mDisplay = EGL_NO_DISPLAY;
- EGLSurface mSurface = EGL_NO_SURFACE;
- EGLContext mContext = EGL_NO_CONTEXT;
-
- EGLContext mPreviousContext = EGL_NO_CONTEXT;
- EGLSurface mPreviousReadSurface = EGL_NO_SURFACE;
- EGLSurface mPreviousDrawSurface = EGL_NO_SURFACE;
-
- bool mIsBound = false;
-};
-
-} // namespace
-
-/*static*/
-std::unique_ptr<DisplaySurfaceGl> DisplaySurfaceGl::createPbufferSurface(
- EGLDisplay display,
- EGLConfig config,
- EGLContext shareContext,
- const EGLint* contextAttribs,
- EGLint width,
- EGLint height) {
- EGLContext context = s_egl.eglCreateContext(display, config, shareContext, contextAttribs);
- if (context == EGL_NO_CONTEXT) {
- ERR("Failed to create context for DisplaySurfaceGl.");
- return nullptr;
- }
-
- const EGLint surfaceAttribs[] = {
- EGL_WIDTH, width, //
- EGL_HEIGHT, height, //
- EGL_NONE, //
- };
- EGLSurface surface = s_egl.eglCreatePbufferSurface(display, config, surfaceAttribs);
- if (surface == EGL_NO_SURFACE) {
- ERR("Failed to create pbuffer surface for DisplaySurfaceGl.");
- return nullptr;
- }
-
- return std::unique_ptr<DisplaySurfaceGl>(new DisplaySurfaceGl(display, surface, context));
-}
-
-/*static*/
-std::unique_ptr<DisplaySurfaceGl> DisplaySurfaceGl::createWindowSurface(
- EGLDisplay display,
- EGLConfig config,
- EGLContext shareContext,
- const GLint* contextAttribs,
- FBNativeWindowType window) {
- EGLContext context = s_egl.eglCreateContext(display, config, shareContext, contextAttribs);
- if (context == EGL_NO_CONTEXT) {
- ERR("Failed to create context for DisplaySurfaceGl.");
- return nullptr;
- }
-
- EGLSurface surface = s_egl.eglCreateWindowSurface(display, config, window, nullptr);
- if (surface == EGL_NO_SURFACE) {
- ERR("Failed to create window surface for DisplaySurfaceGl.");
- return nullptr;
- }
-
- return std::unique_ptr<DisplaySurfaceGl>(new DisplaySurfaceGl(display, surface, context));
-}
-
-DisplaySurfaceGl::DisplaySurfaceGl(EGLDisplay display,
- EGLSurface surface,
- EGLContext context)
- : mDisplay(display),
- mSurface(surface),
- mContext(context),
- mContextHelper(new DisplaySurfaceGlContextHelper(display, surface, context)) {}
-
-DisplaySurfaceGl::~DisplaySurfaceGl() {
- if (mDisplay != EGL_NO_DISPLAY) {
- if (mSurface) {
- s_egl.eglDestroySurface(mDisplay, mSurface);
- }
- if (mContext) {
- s_egl.eglDestroyContext(mDisplay, mContext);
- }
- }
-}
diff --git a/stream-servers/gl/DisplaySurfaceGl.h b/stream-servers/gl/DisplaySurfaceGl.h
deleted file mode 100644
index e682053..0000000
--- a/stream-servers/gl/DisplaySurfaceGl.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// 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.
-
-#pragma once
-
-#include <cstdint>
-#include <memory>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-#include "ContextHelper.h"
-#include "DisplaySurface.h"
-#include "render-utils/render_api_platform_types.h"
-
-class DisplaySurfaceGl : public gfxstream::DisplaySurfaceImpl {
- public:
- static std::unique_ptr<DisplaySurfaceGl> createPbufferSurface(EGLDisplay display,
- EGLConfig config,
- EGLContext shareContext,
- const EGLint* contextAttribs,
- EGLint width,
- EGLint height);
-
- static std::unique_ptr<DisplaySurfaceGl> createWindowSurface(EGLDisplay display,
- EGLConfig config,
- EGLContext shareContext,
- const GLint* contextAttribs,
- FBNativeWindowType window);
-
- ~DisplaySurfaceGl();
-
- ContextHelper* getContextHelper() const { return mContextHelper.get(); }
-
- EGLContext getContextForShareContext() const { return mContext; }
-
- EGLSurface getSurface() const { return mSurface; }
-
- private:
- friend class DisplayGl;
-
- DisplaySurfaceGl(EGLDisplay display,
- EGLSurface surface,
- EGLContext context);
-
- EGLDisplay mDisplay = EGL_NO_DISPLAY;
- EGLSurface mSurface = EGL_NO_SURFACE;
- EGLContext mContext = EGL_NO_CONTEXT;
-
- std::unique_ptr<ContextHelper> mContextHelper;
-};