Revert "(Reland) Rename ColorBuffer to ColorBufferGl and add Col..."
Revert submission 2442579-revert-2383058-revert-2318952-JRCOFEFCOJ-MCGBSQEWLC
Reason for revert: Media failures b/270230549
Reverted changes: /q/submissionid:2442579-revert-2383058-revert-2318952-JRCOFEFCOJ-MCGBSQEWLC
Change-Id: I29c91ce6cb7415b73f3ea6d0a780ccc1d01894d4
diff --git a/stream-servers/Android.bp b/stream-servers/Android.bp
index 00946af..2079cd4 100644
--- a/stream-servers/Android.bp
+++ b/stream-servers/Android.bp
@@ -57,7 +57,6 @@
],
srcs: [
"ChannelStream.cpp",
- "ColorBuffer.cpp",
"DisplaySurface.cpp",
"DisplaySurfaceUser.cpp",
"Hwc2.cpp",
diff --git a/stream-servers/CMakeLists.txt b/stream-servers/CMakeLists.txt
index 864e6ba..ead0364 100644
--- a/stream-servers/CMakeLists.txt
+++ b/stream-servers/CMakeLists.txt
@@ -13,7 +13,6 @@
# Stream server core
set(stream-server-core-sources
- ColorBuffer.cpp
GfxStreamAgents.cpp
VirtioGpuTimelines.cpp
VsyncThread.cpp
diff --git a/stream-servers/ColorBuffer.cpp b/stream-servers/ColorBuffer.cpp
deleted file mode 100644
index 7d8cc68..0000000
--- a/stream-servers/ColorBuffer.cpp
+++ /dev/null
@@ -1,451 +0,0 @@
-// Copyright 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 expresso or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "ColorBuffer.h"
-
-#include "gl/EmulationGl.h"
-#include "vulkan/VkCommonOperations.h"
-
-using android::base::ManagedDescriptor;
-using emugl::ABORT_REASON_OTHER;
-using emugl::FatalError;
-
-namespace {
-
-// ColorBufferVk natively supports YUV images. However, ColorBufferGl
-// needs to emulate YUV support by having an underlying RGBA texture
-// and adding in additional YUV<->RGBA conversions when needed. The
-// memory should not be shared between the VK YUV image and the GL RGBA
-// texture.
-bool shouldAttemptExternalMemorySharing(FrameworkFormat format) {
- return format == FrameworkFormat::FRAMEWORK_FORMAT_GL_COMPATIBLE;
-}
-
-} // namespace
-
-ColorBuffer::ColorBuffer(HandleType handle, uint32_t width, uint32_t height, GLenum format,
- FrameworkFormat frameworkFormat)
- : mHandle(handle),
- mWidth(width),
- mHeight(height),
- mFormat(format),
- mFrameworkFormat(frameworkFormat) {}
-
-/*static*/
-std::shared_ptr<ColorBuffer> ColorBuffer::create(gfxstream::EmulationGl* emulationGl,
- goldfish_vk::VkEmulation* emulationVk,
- uint32_t width, uint32_t height, GLenum format,
- FrameworkFormat frameworkFormat,
- HandleType handle) {
- std::shared_ptr<ColorBuffer> colorBuffer(
- new ColorBuffer(handle, width, height, format, frameworkFormat));
-
- if (emulationGl) {
- colorBuffer->mColorBufferGl =
- emulationGl->createColorBuffer(width, height, format, frameworkFormat, handle);
- if (!colorBuffer->mColorBufferGl) {
- ERR("Failed to initialize ColorBufferGl.");
- return nullptr;
- }
- }
-
- if (emulationVk && emulationVk->live) {
- const bool vulkanOnly = colorBuffer->mColorBufferGl == nullptr;
-
- colorBuffer->mColorBufferVk = std::make_unique<ColorBufferVk>();
- if (!goldfish_vk::setupVkColorBuffer(width, height, format, frameworkFormat, handle,
- vulkanOnly, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
- ERR("Failed to initialize ColorBufferVk.");
- return nullptr;
- }
- }
-
- if (colorBuffer->mColorBufferGl && colorBuffer->mColorBufferVk &&
- shouldAttemptExternalMemorySharing(frameworkFormat)) {
- auto memoryExport = goldfish_vk::exportColorBufferMemory(handle);
- if (memoryExport) {
- if (colorBuffer->mColorBufferGl->importMemory(
- std::move(memoryExport->descriptor), memoryExport->size,
- /*dedicated=*/false, memoryExport->linearTiling)) {
- colorBuffer->mGlAndVkAreSharingExternalMemory = true;
- } else {
- ERR("Failed to import memory to ColorBufferGl:%d", handle);
- return nullptr;
- }
- }
- }
-
- return colorBuffer;
-}
-
-/*static*/
-std::shared_ptr<ColorBuffer> ColorBuffer::onLoad(gfxstream::EmulationGl* emulationGl,
- goldfish_vk::VkEmulation*,
- android::base::Stream* stream) {
- const auto handle = static_cast<HandleType>(stream->getBe32());
- const auto width = static_cast<uint32_t>(stream->getBe32());
- const auto height = static_cast<uint32_t>(stream->getBe32());
- const auto format = static_cast<GLenum>(stream->getBe32());
- const auto frameworkFormat = static_cast<FrameworkFormat>(stream->getBe32());
-
- std::shared_ptr<ColorBuffer> colorBuffer(
- new ColorBuffer(handle, width, height, format, frameworkFormat));
-
- if (emulationGl) {
- colorBuffer->mColorBufferGl = emulationGl->loadColorBuffer(stream);
- if (!colorBuffer->mColorBufferGl) {
- ERR("Failed to load ColorBufferGl.");
- return nullptr;
- }
- }
-
- colorBuffer->mNeedRestore = true;
-
- return colorBuffer;
-}
-
-void ColorBuffer::onSave(android::base::Stream* stream) {
- stream->putBe32(getHndl());
- stream->putBe32(mWidth);
- stream->putBe32(mHeight);
- stream->putBe32(static_cast<uint32_t>(mFormat));
- stream->putBe32(static_cast<uint32_t>(mFrameworkFormat));
-
- if (mColorBufferGl) {
- mColorBufferGl->onSave(stream);
- }
-}
-
-void ColorBuffer::restore() {
- if (mColorBufferGl) {
- mColorBufferGl->restore();
- }
-}
-
-void ColorBuffer::readToBytes(int x, int y, int width, int height, GLenum pixelsFormat,
- GLenum pixelsType, void* outPixels) {
- touch();
-
- if (mColorBufferVk) {
- goldfish_vk::readColorBufferToBytes(mHandle, x, y, width, height, outPixels);
- return;
- }
- if (mColorBufferGl) {
- mColorBufferGl->readPixels(x, y, width, height, pixelsFormat, pixelsType, outPixels);
- return;
- }
-
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "No ColorBuffer impl?";
-}
-
-void ColorBuffer::readToBytesScaled(int pixelsWidth, int pixelsHeight, GLenum pixelsFormat,
- GLenum pixelsType, int pixelsRotation, emugl::Rect rect,
- void* outPixels) {
- touch();
-
- if (mColorBufferGl) {
- mColorBufferGl->readPixelsScaled(pixelsWidth, pixelsHeight, pixelsFormat, pixelsType,
- pixelsRotation, rect, outPixels);
- return;
- }
-
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "Unimplemented.";
-}
-
-void ColorBuffer::readYuvToBytes(int x, int y, int width, int height, void* outPixels,
- uint32_t pixelsSize) {
- touch();
-
- if (mColorBufferVk) {
- goldfish_vk::readColorBufferToBytes(mHandle, x, y, width, height, outPixels);
- return;
- }
- if (mColorBufferGl) {
- mColorBufferGl->readPixelsYUVCached(x, y, width, height, outPixels, pixelsSize);
- return;
- }
-
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "No ColorBuffer impl?";
-}
-
-bool ColorBuffer::updateFromBytes(int x, int y, int width, int height,
- FrameworkFormat frameworkFormat, GLenum pixelsFormat,
- GLenum pixelsType, const void* pixels) {
- touch();
-
- if (mColorBufferVk) {
- return goldfish_vk::updateColorBufferFromBytes(mHandle, x, y, width, height, pixels);
- }
- if (mColorBufferGl) {
- mColorBufferGl->subUpdateFromFrameworkFormat(x, y, width, height, frameworkFormat,
- pixelsFormat, pixelsType, pixels);
- return true;
- }
-
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "No ColorBuffer impl?";
- return false;
-}
-
-bool ColorBuffer::updateFromBytes(int x, int y, int width, int height, GLenum pixelsFormat,
- GLenum pixelsType, const void* pixels) {
- touch();
-
- if (mColorBufferVk) {
- return goldfish_vk::updateColorBufferFromBytes(mHandle, x, y, width, height, pixels);
- }
- if (mColorBufferGl) {
- mColorBufferGl->subUpdate(x, y, width, height, pixelsFormat, pixelsType, pixels);
- return true;
- }
-
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "No ColorBuffer impl?";
- return false;
-}
-
-bool ColorBuffer::updateGlFromBytes(const void* bytes, std::size_t bytesSize) {
- if (mColorBufferGl) {
- touch();
-
- return mColorBufferGl->replaceContents(bytes, bytesSize);
- }
-
- return true;
-}
-
-std::unique_ptr<BorrowedImageInfo> ColorBuffer::borrowForComposition(UsedApi api, bool isTarget) {
- switch (api) {
- case UsedApi::kGl: {
- if (!mColorBufferGl) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "ColorBufferGl not available.";
- }
- return mColorBufferGl->getBorrowedImageInfo();
- }
- case UsedApi::kVk: {
- if (!mColorBufferVk) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "ColorBufferGl not available.";
- }
- return goldfish_vk::borrowColorBufferForComposition(getHndl(), isTarget);
- }
- }
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "Unimplemented";
- return nullptr;
-}
-
-std::unique_ptr<BorrowedImageInfo> ColorBuffer::borrowForDisplay(UsedApi api) {
- switch (api) {
- case UsedApi::kGl: {
- if (!mColorBufferGl) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "ColorBufferGl not available.";
- }
- return mColorBufferGl->getBorrowedImageInfo();
- }
- case UsedApi::kVk: {
- if (!mColorBufferVk) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "ColorBufferGl not available.";
- }
- return goldfish_vk::borrowColorBufferForDisplay(getHndl());
- }
- }
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "Unimplemented";
- return nullptr;
-}
-
-void ColorBuffer::updateFromGl() {
- if (!(mColorBufferGl && mColorBufferVk)) {
- return;
- }
-
- if (mGlAndVkAreSharingExternalMemory) {
- return;
- }
-
- std::size_t contentsSize = 0;
- if (!mColorBufferGl->readContents(&contentsSize, nullptr)) {
- ERR("Failed to get GL contents size for ColorBuffer:%d", mHandle);
- return;
- }
-
- std::vector<uint8_t> contents(contentsSize, 0);
-
- if (!mColorBufferGl->readContents(&contentsSize, contents.data())) {
- ERR("Failed to get GL contents for ColorBuffer:%d", mHandle);
- return;
- }
-
- if (!goldfish_vk::updateColorBufferFromBytes(mHandle, contents)) {
- ERR("Failed to set VK contents for ColorBuffer:%d", mHandle);
- return;
- }
-}
-
-void ColorBuffer::updateFromVk() {
- if (!(mColorBufferGl && mColorBufferVk)) {
- return;
- }
-
- if (mGlAndVkAreSharingExternalMemory) {
- return;
- }
-
- std::vector<uint8_t> contents;
- if (!goldfish_vk::readColorBufferToBytes(mHandle, &contents)) {
- ERR("Failed to get VK contents for ColorBuffer:%d", mHandle);
- return;
- }
-
- if (contents.empty()) return;
-
- if (!mColorBufferGl->replaceContents(contents.data(), contents.size())) {
- ERR("Failed to set GL contents for ColorBuffer:%d", mHandle);
- return;
- }
-}
-
-bool ColorBuffer::glOpBlitFromCurrentReadBuffer() {
- if (!mColorBufferGl) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "ColorBufferGl not available.";
- }
-
- touch();
-
- return mColorBufferGl->blitFromCurrentReadBuffer();
-}
-
-bool ColorBuffer::glOpBindToTexture() {
- if (!mColorBufferGl) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "ColorBufferGl not available.";
- }
-
- touch();
-
- return mColorBufferGl->bindToTexture();
-}
-
-bool ColorBuffer::glOpBindToTexture2() {
- if (!mColorBufferGl) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "ColorBufferGl not available.";
- }
-
- return mColorBufferGl->bindToTexture2();
-}
-
-bool ColorBuffer::glOpBindToRenderbuffer() {
- if (!mColorBufferGl) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "ColorBufferGl not available.";
- }
-
- touch();
-
- return mColorBufferGl->bindToRenderbuffer();
-}
-
-GLuint ColorBuffer::glOpGetTexture() {
- if (!mColorBufferGl) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "ColorBufferGl not available.";
- }
-
- touch();
-
- return mColorBufferGl->getTexture();
-}
-
-void ColorBuffer::glOpReadback(unsigned char* img, bool readbackBgra) {
- if (!mColorBufferGl) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "ColorBufferGl not available.";
- }
-
- touch();
-
- return mColorBufferGl->readback(img, readbackBgra);
-}
-
-void ColorBuffer::glOpReadbackAsync(GLuint buffer, bool readbackBgra) {
- if (!mColorBufferGl) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "ColorBufferGl not available.";
- }
-
- touch();
-
- mColorBufferGl->readbackAsync(buffer, readbackBgra);
-}
-
-bool ColorBuffer::glOpImportEglImage(void* image, bool preserveContent) {
- if (!mColorBufferGl) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "ColorBufferGl not available.";
- }
-
- return mColorBufferGl->importEglImage(image, preserveContent);
-}
-
-bool ColorBuffer::glOpImportEglNativePixmap(void* pixmap, bool preserveContent) {
- if (!mColorBufferGl) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "ColorBufferGl not available.";
- }
-
- return mColorBufferGl->importEglNativePixmap(pixmap, preserveContent);
-}
-
-void ColorBuffer::glOpSwapYuvTexturesAndUpdate(GLenum format, GLenum type,
- FrameworkFormat frameworkFormat, GLuint* textures) {
- if (!mColorBufferGl) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "ColorBufferGl not available.";
- }
-
- mColorBufferGl->swapYUVTextures(frameworkFormat, textures);
-
- // This makes ColorBufferGl regenerate the RGBA texture using
- // YUVConverter::drawConvert() with the updated YUV textures.
- mColorBufferGl->subUpdate(0, 0, mWidth, mHeight, format, type, nullptr);
-
- updateFromGl();
-}
-
-bool ColorBuffer::glOpReadContents(size_t* outNumBytes, void* outContents) {
- if (!mColorBufferGl) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "ColorBufferGl not available.";
- }
-
- return mColorBufferGl->readContents(outNumBytes, outContents);
-}
-
-bool ColorBuffer::glOpReplaceContents(size_t numBytes, const void* contents) {
- if (mColorBufferGl) {
- return mColorBufferGl->replaceContents(contents, numBytes);
- }
- return false;
-}
-
-bool ColorBuffer::glOpIsFastBlitSupported() const {
- if (!mColorBufferGl) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "ColorBufferGl not available.";
- }
-
- return mColorBufferGl->isFastBlitSupported();
-}
-
-void ColorBuffer::glOpPostLayer(const ComposeLayer& l, int frameWidth, int frameHeight) {
- if (!mColorBufferGl) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "ColorBufferGl not available.";
- }
-
- mColorBufferGl->postLayer(l, frameWidth, frameHeight);
-}
-
-void ColorBuffer::glOpPostViewportScaledWithOverlay(float rotation, float dx, float dy) {
- if (!mColorBufferGl) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "ColorBufferGl not available.";
- }
-
- mColorBufferGl->postViewportScaledWithOverlay(rotation, dx, dy);
-}
diff --git a/stream-servers/ColorBuffer.h b/stream-servers/ColorBuffer.h
deleted file mode 100644
index 09c7f6c..0000000
--- a/stream-servers/ColorBuffer.h
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 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 expresso or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#pragma once
-
-#include <memory>
-
-#include "BorrowedImage.h"
-#include "FrameworkFormats.h"
-#include "Handle.h"
-#include "Hwc2.h"
-#include "aemu/base/files/Stream.h"
-#include "gl/ColorBufferGl.h"
-#include "render-utils/Renderer.h"
-#include "snapshot/LazySnapshotObj.h"
-
-namespace gfxstream {
-class EmulationGl;
-} // namespace gfxstream
-namespace goldfish_vk {
-struct VkEmulation;
-} // namespace goldfish_vk
-
-class ColorBuffer : public android::snapshot::LazySnapshotObj<ColorBuffer> {
- public:
- static std::shared_ptr<ColorBuffer> create(gfxstream::EmulationGl* emulationGl,
- goldfish_vk::VkEmulation* emulationVk,
- uint32_t width, uint32_t height, GLenum format,
- FrameworkFormat frameworkFormat, HandleType handle);
-
- static std::shared_ptr<ColorBuffer> onLoad(gfxstream::EmulationGl* emulationGl,
- goldfish_vk::VkEmulation* emulationVk,
- android::base::Stream* stream);
- void onSave(android::base::Stream* stream);
- void restore();
-
- HandleType getHndl() const { return mHandle; }
- uint32_t getWidth() const { return mWidth; }
- uint32_t getHeight() const { return mHeight; }
- GLenum getFormat() const { return mFormat; }
- FrameworkFormat getFrameworkFormat() const { return mFrameworkFormat; }
-
- void readToBytes(int x, int y, int width, int height, GLenum pixelsFormat, GLenum pixelsType,
- void* outPixels);
- void readToBytesScaled(int pixelsWidth, int pixelsHeight, GLenum pixelsFormat,
- GLenum pixelsType, int pixelsRotation, emugl::Rect rect,
- void* outPixels);
- void readYuvToBytes(int x, int y, int width, int height, void* outPixels, uint32_t pixelsSize);
-
- bool updateFromBytes(int x, int y, int width, int height, GLenum pixelsFormat,
- GLenum pixelsType, const void* pixels);
- bool updateFromBytes(int x, int y, int width, int height, FrameworkFormat frameworkFormat,
- GLenum pixelsFormat, GLenum pixelsType, const void* pixels);
- bool updateGlFromBytes(const void* bytes, std::size_t bytesSize);
-
- enum class UsedApi {
- kGl,
- kVk,
- };
- std::unique_ptr<BorrowedImageInfo> borrowForComposition(UsedApi api, bool isTarget);
- std::unique_ptr<BorrowedImageInfo> borrowForDisplay(UsedApi api);
-
- void updateFromGl();
- void updateFromVk();
-
- GLuint glOpGetTexture();
- bool glOpBlitFromCurrentReadBuffer();
- bool glOpBindToTexture();
- bool glOpBindToTexture2();
- bool glOpBindToRenderbuffer();
- void glOpReadback(unsigned char* img, bool readbackBgra);
- void glOpReadbackAsync(GLuint buffer, bool readbackBgra);
- bool glOpImportEglImage(void* image, bool preserveContent);
- bool glOpImportEglNativePixmap(void* pixmap, bool preserveContent);
- void glOpSwapYuvTexturesAndUpdate(GLenum format, GLenum type, FrameworkFormat frameworkFormat,
- GLuint* textures);
- bool glOpReadContents(size_t* outNumBytes, void* outContents);
- bool glOpReplaceContents(size_t numBytes, const void* contents);
- bool glOpIsFastBlitSupported() const;
- void glOpPostLayer(const ComposeLayer& l, int frameWidth, int frameHeight);
- void glOpPostViewportScaledWithOverlay(float rotation, float dx, float dy);
-
- private:
- ColorBuffer(HandleType, uint32_t width, uint32_t height, GLenum format,
- FrameworkFormat frameworkFormat);
-
- const HandleType mHandle;
- const uint32_t mWidth;
- const uint32_t mHeight;
- const GLenum mFormat;
- const FrameworkFormat mFrameworkFormat;
-
- // If GL emulation is enabled.
- std::unique_ptr<gfxstream::ColorBufferGl> mColorBufferGl;
-
- // If Vk emulation is enabled.
- struct ColorBufferVk {
- bool thisIsAPlaceHolder = true;
- };
- std::unique_ptr<ColorBufferVk> mColorBufferVk;
-
- bool mGlAndVkAreSharingExternalMemory = false;
-};
-
-typedef std::shared_ptr<ColorBuffer> ColorBufferPtr;
-
-struct ColorBufferRef {
- ColorBufferPtr cb;
- uint32_t refcount; // number of client-side references
-
- // Tracks whether opened at least once. In O+,
- // color buffers can be created/closed immediately,
- // but then registered (opened) afterwards.
- bool opened;
-
- // Tracks the time when this buffer got a close request while not being
- // opened yet.
- uint64_t closedTs;
-};
-
-typedef std::unordered_map<HandleType, ColorBufferRef> ColorBufferMap;
-typedef std::unordered_multiset<HandleType> ColorBufferSet;
\ No newline at end of file
diff --git a/stream-servers/FrameBuffer.cpp b/stream-servers/FrameBuffer.cpp
index 2126e62..04b344f 100644
--- a/stream-servers/FrameBuffer.cpp
+++ b/stream-servers/FrameBuffer.cpp
@@ -229,7 +229,6 @@
if (!vkEmu) {
ERR("Failed to initialize global Vulkan emulation. Disable the Vulkan support.");
}
- fb->m_emulationVk = vkEmu;
}
if (vkEmu) {
fb->m_vulkanEnabled = true;
@@ -444,6 +443,22 @@
}
}
+void FrameBuffer::setColorBufferInUse(
+ uint32_t colorBufferHandle,
+ bool inUse) {
+
+ AutoLock mutex(m_lock);
+
+ ColorBufferPtr colorBuffer = findColorBuffer(colorBufferHandle);
+ if (!colorBuffer) {
+ // bad colorbuffer handle
+ ERR("FB: setColorBufferInUse cb handle %#x not found", colorBufferHandle);
+ return;
+ }
+
+ colorBuffer->setInUse(inUse);
+}
+
void FrameBuffer::fillGLESUsages(android_studio::EmulatorGLESUsages* usages) {
if (s_egl.eglFillUsages) {
s_egl.eglFillUsages(usages);
@@ -647,10 +662,11 @@
res.wait();
if (postOnlyOnMainThread && (PostCmd::Screenshot == post.cmd) &&
emugl::get_emugl_window_operations().isRunningInUiThread()) {
- post.cb->readToBytesScaled(post.screenshot.screenwidth, post.screenshot.screenheight,
- post.screenshot.format, post.screenshot.type,
- post.screenshot.rotation, post.screenshot.rect,
- post.screenshot.pixels);
+ post.cb->readPixelsScaled(post.screenshot.screenwidth,
+ post.screenshot.screenheight,
+ post.screenshot.format, post.screenshot.type,
+ post.screenshot.rotation,
+ post.screenshot.pixels, post.screenshot.rect);
} else {
std::future<void> completeFuture =
m_postThread.enqueue(Post(std::move(post)));
@@ -1055,8 +1071,21 @@
GLenum p_internalFormat,
FrameworkFormat p_frameworkFormat,
HandleType handle) {
- ColorBufferPtr cb = ColorBuffer::create(m_emulationGl.get(), m_emulationVk, p_width, p_height,
- p_internalFormat, p_frameworkFormat, handle);
+ EGLDisplay display = EGL_NO_DISPLAY;
+ ContextHelper* contextHelper = nullptr;
+ TextureDraw* textureDraw = nullptr;
+ bool isFastBlitSupported = false;
+ if (m_emulationGl) {
+ display = getDisplay();
+ contextHelper = getPbufferSurfaceContextHelper();
+ textureDraw = getTextureDraw();
+ isFastBlitSupported = this->isFastBlitSupported();
+ }
+
+ ColorBufferPtr cb(ColorBuffer::create(display, p_width, p_height,
+ p_internalFormat, p_frameworkFormat,
+ handle, contextHelper, textureDraw,
+ isFastBlitSupported, m_guestUsesAngle));
if (cb.get() == nullptr) {
GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
<< "Failed to create ColorBuffer:" << handle << " format:" << p_internalFormat
@@ -1064,6 +1093,27 @@
<< " height:" << p_height;
}
+ if (m_vulkanEnabled) {
+ if (!goldfish_vk::setupVkColorBuffer(
+ p_width, p_height, p_internalFormat, p_frameworkFormat, handle,
+ /*vulkanOnly=*/m_guestUsesAngle, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
+ GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+ << "Failed to create color buffer."
+ << " format:" << p_internalFormat << " width:" << p_width << " height:" << p_height;
+ return 0;
+ }
+
+ auto memoryExport = goldfish_vk::exportColorBufferMemory(handle);
+ if (memoryExport) {
+ if (!cb->importMemory(std::move(memoryExport->descriptor), memoryExport->size,
+ /*dedicated=*/false, memoryExport->linearTiling,
+ /*vulkanOnly*/false)) {
+ ERR("Failed to import memory to ColorBuffer:%d", handle);
+ return 0;
+ }
+ }
+ }
+
assert(m_colorbuffers.count(handle) == 0);
// When guest feature flag RefCountPipe is on, no reference counting is
// needed. We only memoize the mapping from handle to ColorBuffer.
@@ -1862,8 +1912,19 @@
buffer->read(offset, size, bytes);
}
-void FrameBuffer::readColorBuffer(HandleType p_colorbuffer, int x, int y, int width, int height,
- GLenum format, GLenum type, void* pixels) {
+void FrameBuffer::readColorBuffer(HandleType p_colorbuffer,
+ int x,
+ int y,
+ int width,
+ int height,
+ GLenum format,
+ GLenum type,
+ void* pixels) {
+ if (m_guestUsesAngle) {
+ goldfish_vk::readColorBufferToBytes(p_colorbuffer, x, y, width, height, pixels);
+ return;
+ }
+
AutoLock mutex(m_lock);
ColorBufferPtr colorBuffer = findColorBuffer(p_colorbuffer);
@@ -1872,11 +1933,21 @@
return;
}
- colorBuffer->readToBytes(x, y, width, height, format, type, pixels);
+ colorBuffer->readPixels(x, y, width, height, format, type, pixels);
}
-void FrameBuffer::readColorBufferYUV(HandleType p_colorbuffer, int x, int y, int width, int height,
- void* pixels, uint32_t pixels_size) {
+void FrameBuffer::readColorBufferYUV(HandleType p_colorbuffer,
+ int x,
+ int y,
+ int width,
+ int height,
+ void* pixels,
+ uint32_t pixels_size) {
+ if (m_guestUsesAngle) {
+ goldfish_vk::readColorBufferToBytes(p_colorbuffer, x, y, width, height, pixels);
+ return;
+ }
+
AutoLock mutex(m_lock);
ColorBufferPtr colorBuffer = findColorBuffer(p_colorbuffer);
@@ -1885,7 +1956,7 @@
return;
}
- colorBuffer->readYuvToBytes(x, y, width, height, pixels, pixels_size);
+ colorBuffer->readPixelsYUVCached(x, y, width, height, pixels, pixels_size);
}
void FrameBuffer::createYUVTextures(uint32_t type,
@@ -1969,9 +2040,11 @@
// bad colorbuffer handle
return;
}
- colorBuffer->glOpSwapYuvTexturesAndUpdate(
- format, type, static_cast<FrameworkFormat>(texture_type), textures);
+ colorBuffer->swapYUVTextures(texture_type, textures);
}
+
+ updateColorBuffer(p_colorbuffer, x, y, width, height, format, type,
+ nullptr);
}
bool FrameBuffer::updateBuffer(HandleType p_buffer, uint64_t offset, uint64_t size, void* bytes) {
@@ -2004,6 +2077,10 @@
return false;
}
+ if (m_guestUsesAngle) {
+ return goldfish_vk::updateColorBufferFromBytes(p_colorbuffer, x, y, width, height, pixels);
+ }
+
AutoLock mutex(m_lock);
ColorBufferPtr colorBuffer = findColorBuffer(p_colorbuffer);
@@ -2012,7 +2089,7 @@
return false;
}
- colorBuffer->updateFromBytes(x, y, width, height, format, type, pixels);
+ colorBuffer->subUpdate(x, y, width, height, format, type, pixels);
return true;
}
@@ -2033,7 +2110,9 @@
return false;
}
- (*c).second.cb->updateFromBytes(x, y, width, height, fwkFormat, format, type, pixels);
+ (*c).second.cb->subUpdateFromFrameworkFormat(x, y, width, height, fwkFormat, format, type,
+ pixels);
+
return true;
}
@@ -2047,7 +2126,7 @@
return false;
}
- return colorBuffer->glOpReplaceContents(numBytes, pixels);
+ return colorBuffer->replaceContents(pixels, numBytes);
}
bool FrameBuffer::readColorBufferContents(
@@ -2061,7 +2140,7 @@
return false;
}
- return colorBuffer->glOpReadContents(numBytes, pixels);
+ return colorBuffer->readContents(numBytes, pixels);
}
bool FrameBuffer::getColorBufferInfo(
@@ -2078,7 +2157,7 @@
*width = colorBuffer->getWidth();
*height = colorBuffer->getHeight();
- *internalformat = colorBuffer->getFormat();
+ *internalformat = colorBuffer->getInternalFormat();
if (frameworkFormat) {
*frameworkFormat = colorBuffer->getFrameworkFormat();
}
@@ -2109,7 +2188,7 @@
return false;
}
- return colorBuffer->glOpBindToTexture();
+ return colorBuffer->bindToTexture();
}
bool FrameBuffer::bindColorBufferToTexture2(HandleType p_colorbuffer) {
@@ -2126,7 +2205,7 @@
return false;
}
- return colorBuffer->glOpBindToTexture2();
+ return colorBuffer->bindToTexture2();
}
bool FrameBuffer::bindColorBufferToRenderbuffer(HandleType p_colorbuffer) {
@@ -2138,7 +2217,7 @@
return false;
}
- return colorBuffer->glOpBindToRenderbuffer();
+ return colorBuffer->bindToRenderbuffer();
}
bool FrameBuffer::bindContext(HandleType p_context,
@@ -2501,7 +2580,7 @@
doPostCallback(iter.second.img, iter.first);
}
} else {
- cb->glOpReadback(iter.second.img, iter.second.readBgra);
+ cb->readback(iter.second.img, iter.second.readBgra);
doPostCallback(iter.second.img, iter.first);
}
}
@@ -3115,7 +3194,8 @@
m_guestManagedColorBufferLifetime = stream->getByte();
loadCollection(
stream, &m_colorbuffers, [this, now](Stream* stream) -> ColorBufferMap::value_type {
- ColorBufferPtr cb = ColorBuffer::onLoad(m_emulationGl.get(), m_emulationVk, stream);
+ ColorBufferPtr cb(ColorBuffer::onLoad(stream, getDisplay(), getPbufferSurfaceContextHelper(),
+ getTextureDraw(), isFastBlitSupported()));
const HandleType handle = cb->getHndl();
const unsigned refCount = stream->getBe32();
const bool opened = stream->getByte();
@@ -3404,9 +3484,9 @@
switch (type) {
case RESOURCE_TYPE_EGL_NATIVE_PIXMAP:
- return colorBuffer->glOpImportEglNativePixmap(resource, preserveContent);
+ return colorBuffer->importEglNativePixmap(resource, preserveContent);
case RESOURCE_TYPE_EGL_IMAGE:
- return colorBuffer->glOpImportEglImage(resource, preserveContent);
+ return colorBuffer->importEglImage(resource, preserveContent);
default:
ERR("Error: unsupported resource type: %u", type);
return false;
@@ -3451,25 +3531,30 @@
std::unique_ptr<BorrowedImageInfo> FrameBuffer::borrowColorBufferForComposition(
uint32_t colorBufferHandle, bool colorBufferIsTarget) {
+ if (m_useVulkanComposition) {
+ return goldfish_vk::borrowColorBufferForComposition(colorBufferHandle, colorBufferIsTarget);
+ }
+
ColorBufferPtr colorBufferPtr = findColorBuffer(colorBufferHandle);
if (!colorBufferPtr) {
ERR("Failed to get borrowed image info for ColorBuffer:%d", colorBufferHandle);
return nullptr;
}
-
- const auto api = m_useVulkanComposition ? ColorBuffer::UsedApi::kVk : ColorBuffer::UsedApi::kGl;
- return colorBufferPtr->borrowForComposition(api, colorBufferIsTarget);
+ return colorBufferPtr->getBorrowedImageInfo();
}
std::unique_ptr<BorrowedImageInfo> FrameBuffer::borrowColorBufferForDisplay(
- uint32_t colorBufferHandle) {
+ uint32_t colorBufferHandle) {
+ if (m_useVulkanComposition) {
+ return goldfish_vk::borrowColorBufferForDisplay(colorBufferHandle);
+ }
+
ColorBufferPtr colorBufferPtr = findColorBuffer(colorBufferHandle);
if (!colorBufferPtr) {
ERR("Failed to get borrowed image info for ColorBuffer:%d", colorBufferHandle);
return nullptr;
}
- const auto api = m_useVulkanComposition ? ColorBuffer::UsedApi::kVk : ColorBuffer::UsedApi::kGl;
- return colorBufferPtr->borrowForDisplay(api);
+ return colorBufferPtr->getBorrowedImageInfo();
}
gfxstream::EmulationGl& FrameBuffer::getEmulationGl() {
@@ -3685,7 +3770,30 @@
ERR("Failed to find ColorBuffer:%d", colorBufferHandle);
return;
}
- colorBuffer->updateFromGl();
+
+ // TODO(b/233939967): move the below into the generic ColorBuffer.
+
+ if (!goldfish_vk::colorBufferNeedsUpdateBetweenGlAndVk(colorBufferHandle)) {
+ return;
+ }
+
+ std::size_t contentsSize = 0;
+ if (!colorBuffer->readContents(&contentsSize, nullptr)) {
+ ERR("Failed to get GL contents size for ColorBuffer:%d", colorBufferHandle);
+ return;
+ }
+
+ std::vector<uint8_t> contents(contentsSize, 0);
+
+ if (!colorBuffer->readContents(&contentsSize, contents.data())) {
+ ERR("Failed to get GL contents for ColorBuffer:%d", colorBufferHandle);
+ return;
+ }
+
+ if (!goldfish_vk::updateColorBufferFromBytes(colorBufferHandle, contents)) {
+ ERR("Failed to set VK contents for ColorBuffer:%d", colorBufferHandle);
+ return;
+ }
}
void FrameBuffer::updateColorBufferFromVk(HandleType colorBufferHandle) {
@@ -3696,5 +3804,23 @@
ERR("Failed to find ColorBuffer:%d", colorBufferHandle);
return;
}
- colorBuffer->updateFromVk();
+
+ // TODO(b/233939967): move the below into the generic ColorBuffer.
+
+ if (!goldfish_vk::colorBufferNeedsUpdateBetweenGlAndVk(colorBufferHandle)) {
+ return;
+ }
+
+ std::vector<uint8_t> contents;
+ if (!goldfish_vk::readColorBufferToBytes(colorBufferHandle, &contents)) {
+ ERR("Failed to get VK contents for ColorBuffer:%d", colorBufferHandle);
+ return;
+ }
+
+ if (contents.empty()) return;
+
+ if (!colorBuffer->replaceContents(contents.data(), contents.size())) {
+ ERR("Failed to set GL contents for ColorBuffer:%d", colorBufferHandle);
+ return;
+ }
}
diff --git a/stream-servers/FrameBuffer.h b/stream-servers/FrameBuffer.h
index af83273..3799295 100644
--- a/stream-servers/FrameBuffer.h
+++ b/stream-servers/FrameBuffer.h
@@ -557,6 +557,7 @@
bool isVulkanInteropSupported() const { return m_vulkanInteropSupported; }
bool isVulkanEnabled() const { return m_vulkanEnabled; }
+ void setColorBufferInUse(uint32_t colorBufferHandle, bool inUse);
// Fill GLES usage protobuf
void fillGLESUsages(android_studio::EmulatorGLESUsages*);
@@ -854,7 +855,6 @@
Compositor* m_compositor = nullptr;
bool m_useVulkanComposition = false;
- goldfish_vk::VkEmulation* m_emulationVk = nullptr;
// 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 213cd96..58bc5ec 100644
--- a/stream-servers/PostWorker.cpp
+++ b/stream-servers/PostWorker.cpp
@@ -19,10 +19,10 @@
#include <chrono>
-#include "ColorBuffer.h"
#include "FrameBuffer.h"
#include "RenderThreadInfo.h"
#include "aemu/base/Tracing.h"
+#include "gl/ColorBufferGl.h"
#include "gl/DisplayGl.h"
#include "host-common/GfxstreamFatalError.h"
#include "host-common/logging.h"
@@ -332,7 +332,8 @@
GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<
"Screenshot not supported with native Vulkan swapchain enabled.";
}
- cb->readToBytesScaled(width, height, format, type, rotation, rect, pixels);
+ cb->readPixelsScaled(
+ width, height, format, type, rotation, pixels, rect);
}
void PostWorker::block(std::promise<void> scheduledSignal, std::future<void> continueSignal) {
diff --git a/stream-servers/gl/ColorBufferGl.cpp b/stream-servers/gl/ColorBufferGl.cpp
index e12cab9..dc81841 100644
--- a/stream-servers/gl/ColorBufferGl.cpp
+++ b/stream-servers/gl/ColorBufferGl.cpp
@@ -40,7 +40,6 @@
using gfxstream::GLESApi_CM;
using gfxstream::GLESApi_2;
-namespace gfxstream {
namespace {
// Lazily create and bind a framebuffer object to the current host context.
@@ -66,7 +65,7 @@
#if DEBUG_CB_FBO
GLenum status = s_gles2.glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE_OES) {
- ERR("ColorBufferGl::bindFbo: FBO not complete: %#x\n", status);
+ ERR("ColorBuffer::bindFbo: FBO not complete: %#x\n", status);
s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, 0);
s_gles2.glDeleteFramebuffers(1, fbo);
*fbo = 0;
@@ -212,12 +211,16 @@
}
// static
-std::unique_ptr<ColorBufferGl> ColorBufferGl::create(EGLDisplay p_display, int p_width,
- int p_height, GLint p_internalFormat,
- FrameworkFormat p_frameworkFormat,
- HandleType hndl, ContextHelper* helper,
- TextureDraw* textureDraw,
- bool fastBlitSupported) {
+ColorBuffer* ColorBuffer::create(EGLDisplay p_display,
+ int p_width,
+ int p_height,
+ GLint p_internalFormat,
+ FrameworkFormat p_frameworkFormat,
+ HandleType hndl,
+ ContextHelper* helper,
+ TextureDraw* textureDraw,
+ bool fastBlitSupported,
+ bool vulkanOnly) {
GLenum texFormat = 0;
GLenum pixelType = GL_UNSIGNED_BYTE;
int bytesPerPixel = 4;
@@ -227,15 +230,17 @@
if (!sGetFormatParameters(&p_internalFormat, &texFormat, &pixelType,
&bytesPerPixel, &p_sizedInternalFormat,
&isBlob)) {
- fprintf(stderr, "ColorBufferGl::create invalid format 0x%x\n", p_internalFormat);
- return nullptr;
+ fprintf(stderr, "ColorBuffer::create invalid format 0x%x\n",
+ p_internalFormat);
+ return NULL;
}
const unsigned long bufsize = ((unsigned long)bytesPerPixel) * p_width
* p_height;
// This constructor is private, so std::make_unique can't be used.
- std::unique_ptr<ColorBufferGl> cb{
- new ColorBufferGl(p_display, hndl, p_width, p_height, helper, textureDraw)};
+ std::unique_ptr<ColorBuffer> cb{new ColorBuffer(p_display, hndl, helper, textureDraw)};
+ cb->m_width = p_width;
+ cb->m_height = p_height;
cb->m_internalFormat = p_internalFormat;
cb->m_sizedInternalFormat = p_sizedInternalFormat;
cb->m_format = texFormat;
@@ -243,13 +248,18 @@
cb->m_frameworkFormat = p_frameworkFormat;
cb->m_fastBlitSupported = fastBlitSupported;
cb->m_numBytes = (size_t)bufsize;
+ cb->m_vulkanOnly = vulkanOnly;
+
+ if (vulkanOnly) {
+ return cb.release();
+ }
RecursiveScopedContextBind context(helper);
if (!context.isOk()) {
- return nullptr;
+ return NULL;
}
- GL_SCOPED_DEBUG_GROUP("ColorBufferGl::create(handle:%d)", hndl);
+ GL_SCOPED_DEBUG_GROUP("ColorBuffer::create(handle:%d)", hndl);
GLint prevUnpackAlignment;
s_gles2.glGetIntegerv(GL_UNPACK_ALIGNMENT, &prevUnpackAlignment);
@@ -320,19 +330,18 @@
s_gles2.glPixelStorei(GL_UNPACK_ALIGNMENT, prevUnpackAlignment);
s_gles2.glFinish();
- return cb;
+ return cb.release();
}
-ColorBufferGl::ColorBufferGl(EGLDisplay display, HandleType hndl, GLuint width, GLuint height,
- ContextHelper* helper, TextureDraw* textureDraw)
- : m_width(width),
- m_height(height),
- m_display(display),
- m_helper(helper),
- m_textureDraw(textureDraw),
- mHndl(hndl) {}
+ColorBuffer::ColorBuffer(EGLDisplay display, HandleType hndl, ContextHelper* helper,
+ TextureDraw* textureDraw)
+ : m_display(display), m_helper(helper), m_textureDraw(textureDraw), mHndl(hndl) {}
-ColorBufferGl::~ColorBufferGl() {
+ColorBuffer::~ColorBuffer() {
+ if (m_vulkanOnly) {
+ return;
+ }
+
RecursiveScopedContextBind context(m_helper);
if (m_blitEGLImage) {
@@ -366,18 +375,22 @@
delete m_resizer;
}
-void ColorBufferGl::readPixels(int x, int y, int width, int height, GLenum p_format, GLenum p_type,
- void* pixels) {
+void ColorBuffer::readPixels(int x,
+ int y,
+ int width,
+ int height,
+ GLenum p_format,
+ GLenum p_type,
+ void* pixels) {
RecursiveScopedContextBind context(m_helper);
if (!context.isOk()) {
return;
}
- GL_SCOPED_DEBUG_GROUP("ColorBufferGl::readPixels(handle:%d fbo:%d tex:%d)", mHndl, m_fbo,
- m_tex);
+ GL_SCOPED_DEBUG_GROUP("ColorBuffer::readPixels(handle:%d fbo:%d tex:%d)", mHndl, m_fbo, m_tex);
p_format = sGetUnsizedColorBufferFormat(p_format);
-
+ touch();
waitSync();
if (bindFbo(&m_fbo, m_tex, m_needFboReattach)) {
@@ -391,8 +404,8 @@
}
}
-void ColorBufferGl::readPixelsScaled(int width, int height, GLenum p_format, GLenum p_type,
- int rotation, emugl::Rect rect, void* pixels) {
+void ColorBuffer::readPixelsScaled(int width, int height, GLenum p_format, GLenum p_type,
+ int rotation, void* pixels, emugl::Rect rect) {
RecursiveScopedContextBind context(m_helper);
if (!context.isOk()) {
return;
@@ -408,7 +421,7 @@
return;
}
p_format = sGetUnsizedColorBufferFormat(p_format);
-
+ touch();
waitSync();
GLuint tex = m_resizer->update(m_tex, width, height, rotation);
if (bindFbo(&m_scaleRotationFbo, tex, m_needFboReattach)) {
@@ -453,13 +466,18 @@
}
}
-void ColorBufferGl::readPixelsYUVCached(int x, int y, int width, int height, void* pixels,
- uint32_t pixels_size) {
+void ColorBuffer::readPixelsYUVCached(int x,
+ int y,
+ int width,
+ int height,
+ void* pixels,
+ uint32_t pixels_size) {
RecursiveScopedContextBind context(m_helper);
if (!context.isOk()) {
return;
}
+ touch();
waitSync();
#if DEBUG_CB_FBO
@@ -469,12 +487,17 @@
assert(m_yuv_converter.get());
#endif
- m_yuv_converter->readPixels((uint8_t*)pixels, pixels_size);
+ if (!m_vulkanOnly) {
+ m_yuv_converter->readPixels((uint8_t*)pixels, pixels_size);
+ } else {
+ GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<
+ "Unexpected function call when m_vulkanOnly";
+ }
return;
}
-void ColorBufferGl::reformat(GLint internalformat, GLenum type) {
+void ColorBuffer::reformat(GLint internalformat, GLenum type) {
GLenum texFormat = internalformat;
GLenum pixelType = GL_UNSIGNED_BYTE;
GLint sizedInternalFormat = GL_RGBA8;
@@ -536,9 +559,14 @@
m_numBytes = bpp * m_width * m_height;
}
-void ColorBufferGl::swapYUVTextures(FrameworkFormat type, uint32_t* textures) {
- if (type == FrameworkFormat::FRAMEWORK_FORMAT_NV12) {
- m_yuv_converter->swapTextures(type, textures);
+void ColorBuffer::swapYUVTextures(uint32_t type, uint32_t* textures) {
+ if (type == FRAMEWORK_FORMAT_NV12) {
+ if (!m_vulkanOnly) {
+ m_yuv_converter->swapTextures(type, textures);
+ } else {
+ GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+ << "Unexpected function call when m_vulkanOnly";
+ }
} else {
fprintf(stderr,
"%s: ERROR: format other than NV12 is not supported: 0x%x\n",
@@ -546,21 +574,31 @@
}
}
-void ColorBufferGl::subUpdate(int x, int y, int width, int height, GLenum p_format, GLenum p_type,
- const void* pixels) {
+void ColorBuffer::subUpdate(int x,
+ int y,
+ int width,
+ int height,
+ GLenum p_format,
+ GLenum p_type,
+ void* pixels) {
+ if (m_vulkanOnly) {
+ return;
+ }
subUpdateFromFrameworkFormat(x, y, width, height, m_frameworkFormat, p_format, p_type, pixels);
}
-void ColorBufferGl::subUpdateFromFrameworkFormat(int x, int y, int width, int height,
- FrameworkFormat fwkFormat, GLenum p_format,
- GLenum p_type, const void* pixels) {
+void ColorBuffer::subUpdateFromFrameworkFormat(int x, int y, int width, int height,
+ FrameworkFormat fwkFormat, GLenum p_format,
+ GLenum p_type, void* pixels) {
const GLenum p_unsizedFormat = sGetUnsizedColorBufferFormat(p_format);
RecursiveScopedContextBind context(m_helper);
if (!context.isOk()) {
return;
}
- GL_SCOPED_DEBUG_GROUP("ColorBufferGl::subUpdate(handle:%d fbo:%d tex:%d)", mHndl, m_fbo, m_tex);
+ GL_SCOPED_DEBUG_GROUP("ColorBuffer::subUpdate(handle:%d fbo:%d tex:%d)", mHndl, m_fbo, m_tex);
+
+ touch();
if (m_needFormatCheck) {
if (p_type != m_type || p_format != m_format) {
@@ -595,7 +633,7 @@
}
}
-bool ColorBufferGl::replaceContents(const void* newContents, size_t numBytes) {
+bool ColorBuffer::replaceContents(const void* newContents, size_t numBytes) {
if (m_vulkanOnly) {
return false;
}
@@ -618,6 +656,8 @@
return false;
}
+ touch();
+
s_gles2.glBindTexture(GL_TEXTURE_2D, m_tex);
s_gles2.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
s_gles2.glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_width, m_height, m_format,
@@ -631,7 +671,7 @@
return true;
}
-bool ColorBufferGl::readContents(size_t* numBytes, void* pixels) {
+bool ColorBuffer::readContents(size_t* numBytes, void* pixels) {
if (m_yuv_converter) {
// common code path for vk & gles
*numBytes = m_yuv_converter->getDataSize();
@@ -651,7 +691,7 @@
}
}
-bool ColorBufferGl::blitFromCurrentReadBuffer() {
+bool ColorBuffer::blitFromCurrentReadBuffer() {
RenderThreadInfoGl* const tInfo = RenderThreadInfoGl::get();
if (!tInfo) {
GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
@@ -663,6 +703,8 @@
return false;
}
+ touch();
+
if (m_fastBlitSupported) {
s_egl.eglBlitFromCurrentReadBufferANDROID(m_display, m_eglImage);
m_sync = (GLsync)s_egl.eglSetImageFenceANDROID(m_display, m_eglImage);
@@ -813,7 +855,7 @@
return true;
}
-bool ColorBufferGl::bindToTexture() {
+bool ColorBuffer::bindToTexture() {
if (!m_eglImage) {
return false;
}
@@ -827,6 +869,7 @@
if (!tInfo->currContext.get()) {
return false;
}
+ touch();
if (tInfo->currContext->clientVersion() > GLESApi_CM) {
s_gles2.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage);
@@ -836,7 +879,7 @@
return true;
}
-bool ColorBufferGl::bindToTexture2() {
+bool ColorBuffer::bindToTexture2() {
if (!m_eglImage) {
return false;
}
@@ -845,7 +888,7 @@
return true;
}
-bool ColorBufferGl::bindToRenderbuffer() {
+bool ColorBuffer::bindToRenderbuffer() {
if (!m_eglImage) {
return false;
}
@@ -859,7 +902,7 @@
if (!tInfo->currContext.get()) {
return false;
}
-
+ touch();
if (tInfo->currContext->clientVersion() > GLESApi_CM) {
s_gles2.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER_OES,
m_eglImage);
@@ -870,38 +913,40 @@
return true;
}
-GLuint ColorBufferGl::getViewportScaledTexture() { return m_resizer->update(m_tex); }
+GLuint ColorBuffer::getViewportScaledTexture() {
+ return m_resizer->update(m_tex);
+}
-void ColorBufferGl::setSync(bool debug) {
+void ColorBuffer::setSync(bool debug) {
m_sync = (GLsync)s_egl.eglSetImageFenceANDROID(m_display, m_eglImage);
if (debug) fprintf(stderr, "%s: %u to %p\n", __func__, getHndl(), m_sync);
}
-void ColorBufferGl::waitSync(bool debug) {
+void ColorBuffer::waitSync(bool debug) {
if (debug) fprintf(stderr, "%s: %u sync %p\n", __func__, getHndl(), m_sync);
if (m_sync) {
s_egl.eglWaitImageFenceANDROID(m_display, m_sync);
}
}
-bool ColorBufferGl::post(GLuint tex, float rotation, float dx, float dy) {
+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);
}
-bool ColorBufferGl::postViewportScaledWithOverlay(float rotation, float dx, float dy) {
+bool ColorBuffer::postWithOverlay(float rotation, float dx, float dy) {
// NOTE: Do not call m_helper->setupContext() here!
waitSync();
return m_textureDraw->drawWithOverlay(getViewportScaledTexture(), rotation, dx, dy);
}
-void ColorBufferGl::readback(unsigned char* img, bool readbackBgra) {
+void ColorBuffer::readback(unsigned char* img, bool readbackBgra) {
RecursiveScopedContextBind context(m_helper);
if (!context.isOk()) {
return;
}
-
+ touch();
waitSync();
if (bindFbo(&m_fbo, m_tex, m_needFboReattach)) {
@@ -915,12 +960,12 @@
}
}
-void ColorBufferGl::readbackAsync(GLuint buffer, bool readbackBgra) {
+void ColorBuffer::readbackAsync(GLuint buffer, bool readbackBgra) {
RecursiveScopedContextBind context(m_helper);
if (!context.isOk()) {
return;
}
-
+ touch();
waitSync();
if (bindFbo(&m_fbo, m_tex, m_needFboReattach)) {
@@ -934,9 +979,11 @@
}
}
-HandleType ColorBufferGl::getHndl() const { return mHndl; }
+HandleType ColorBuffer::getHndl() const {
+ return mHndl;
+}
-void ColorBufferGl::onSave(android::base::Stream* stream) {
+void ColorBuffer::onSave(android::base::Stream* stream) {
stream->putBe32(getHndl());
stream->putBe32(static_cast<uint32_t>(m_width));
stream->putBe32(static_cast<uint32_t>(m_height));
@@ -949,10 +996,11 @@
stream->putBe32(m_needFormatCheck);
}
-std::unique_ptr<ColorBufferGl> ColorBufferGl::onLoad(android::base::Stream* stream,
- EGLDisplay p_display, ContextHelper* helper,
- TextureDraw* textureDraw,
- bool fastBlitSupported) {
+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());
GLuint height = static_cast<GLuint>(stream->getBe32());
@@ -967,11 +1015,13 @@
return create(p_display, width, height, internalFormat, frameworkFormat,
hndl, helper, textureDraw, fastBlitSupported);
}
- std::unique_ptr<ColorBufferGl> cb(
- new ColorBufferGl(p_display, hndl, width, height, helper, textureDraw));
+ ColorBuffer* cb = new ColorBuffer(p_display, hndl, helper, textureDraw);
+ cb->mNeedRestore = true;
cb->m_eglImage = eglImage;
cb->m_blitEGLImage = blitEGLImage;
assert(eglImage && blitEGLImage);
+ cb->m_width = width;
+ cb->m_height = height;
cb->m_internalFormat = internalFormat;
cb->m_frameworkFormat = frameworkFormat;
cb->m_fastBlitSupported = fastBlitSupported;
@@ -979,7 +1029,7 @@
return cb;
}
-void ColorBufferGl::restore() {
+void ColorBuffer::restore() {
RecursiveScopedContextBind context(m_helper);
s_gles2.glGenTextures(1, &m_tex);
s_gles2.glBindTexture(GL_TEXTURE_2D, m_tex);
@@ -1000,16 +1050,24 @@
}
}
-GLuint ColorBufferGl::getTexture() { return m_tex; }
-void ColorBufferGl::postLayer(const ComposeLayer& l, int frameWidth, int frameHeight) {
+GLuint ColorBuffer::getTexture() {
+ touch();
+ return m_tex;
+}
+
+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,
getViewportScaledTexture());
}
-bool ColorBufferGl::importMemory(ManagedDescriptor externalDescriptor, uint64_t size,
- bool dedicated, bool linearTiling) {
+bool ColorBuffer::importMemory(ManagedDescriptor externalDescriptor, uint64_t size, bool dedicated,
+ bool linearTiling, bool vulkanOnly) {
+ if (m_vulkanOnly) {
+ return true;
+ }
RecursiveScopedContextBind context(m_helper);
s_gles2.glCreateMemoryObjectsEXT(1, &m_memoryObject);
if (dedicated) {
@@ -1054,10 +1112,12 @@
std::vector<uint8_t> prevContents;
- size_t bytes;
- readContents(&bytes, nullptr);
- prevContents.resize(bytes, 0);
- readContents(&bytes, prevContents.data());
+ if (!vulkanOnly) {
+ size_t bytes;
+ readContents(&bytes, nullptr);
+ prevContents.resize(bytes, 0);
+ readContents(&bytes, prevContents.data());
+ }
s_gles2.glDeleteTextures(1, &m_tex);
s_gles2.glGenTextures(1, &m_tex);
@@ -1091,12 +1151,15 @@
m_display, s_egl.eglGetCurrentContext(), EGL_GL_TEXTURE_2D_KHR,
(EGLClientBuffer)SafePointerFromUInt(m_tex), NULL);
- replaceContents(prevContents.data(), m_numBytes);
+ if (!vulkanOnly) {
+ replaceContents(prevContents.data(), m_numBytes);
+ }
return true;
}
-bool ColorBufferGl::importEglNativePixmap(void* pixmap, bool preserveContent) {
+bool ColorBuffer::importEglNativePixmap(void* pixmap, bool preserveContent) {
+
EGLImageKHR image = s_egl.eglCreateImageKHR(m_display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, pixmap, nullptr);
if (image == EGL_NO_IMAGE_KHR) {
@@ -1104,7 +1167,7 @@
return false;
}
- // Assume pixmap is compatible with ColorBufferGl's current dimensions and internal format.
+ // Assume pixmap is compatible with ColorBuffer's current dimensions and internal format.
EGLBoolean setInfoRes = s_egl.eglSetImageInfoANDROID(m_display, image, m_width, m_height, m_internalFormat);
if (EGL_TRUE != setInfoRes) {
@@ -1117,13 +1180,12 @@
return true;
}
-bool ColorBufferGl::importEglImage(void* nativeEglImage, bool preserveContent) {
+bool ColorBuffer::importEglImage(void* nativeEglImage, bool preserveContent) {
EGLImageKHR image = s_egl.eglImportImageANDROID(m_display, (EGLImage)nativeEglImage);
if (image == EGL_NO_IMAGE_KHR) return false;
- // Assume nativeEglImage is compatible with ColorBufferGl's current dimensions and internal
- // format.
+ // Assume nativeEglImage is compatible with ColorBuffer's current dimensions and internal format.
EGLBoolean setInfoRes = s_egl.eglSetImageInfoANDROID(m_display, image, m_width, m_height, m_internalFormat);
if (EGL_TRUE != setInfoRes) {
@@ -1135,7 +1197,7 @@
return true;
}
-std::vector<uint8_t> ColorBufferGl::getContents() {
+std::vector<uint8_t> ColorBuffer::getContents() {
// Assume there is a current context.
size_t bytes;
readContents(&bytes, nullptr);
@@ -1144,20 +1206,20 @@
return contents;
}
-void ColorBufferGl::clearStorage() {
+void ColorBuffer::clearStorage() {
s_gles2.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)NULL);
s_egl.eglDestroyImageKHR(m_display, m_eglImage);
m_eglImage = (EGLImageKHR)0;
}
-void ColorBufferGl::restoreEglImage(EGLImageKHR image) {
+void ColorBuffer::restoreEglImage(EGLImageKHR image) {
s_gles2.glBindTexture(GL_TEXTURE_2D, m_tex);
m_eglImage = image;
s_gles2.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)m_eglImage);
}
-void ColorBufferGl::rebindEglImage(EGLImageKHR image, bool preserveContent) {
+void ColorBuffer::rebindEglImage(EGLImageKHR image, bool preserveContent) {
RecursiveScopedContextBind context(m_helper);
std::vector<uint8_t> contents;
@@ -1172,7 +1234,11 @@
}
}
-std::unique_ptr<BorrowedImageInfo> ColorBufferGl::getBorrowedImageInfo() {
+void ColorBuffer::setInUse(bool inUse) {
+ m_inUse = inUse;
+}
+
+std::unique_ptr<BorrowedImageInfo> ColorBuffer::getBorrowedImageInfo() {
auto info = std::make_unique<BorrowedImageInfoGl>();
info->id = mHndl;
info->width = m_width;
@@ -1181,5 +1247,3 @@
info->onCommandsIssued = [this]() { setSync(); };
return info;
}
-
-} // namespace gfxstream
diff --git a/stream-servers/gl/ColorBufferGl.h b/stream-servers/gl/ColorBufferGl.h
index 5b8bd86..c9f62ce 100644
--- a/stream-servers/gl/ColorBufferGl.h
+++ b/stream-servers/gl/ColorBufferGl.h
@@ -33,6 +33,7 @@
#include "aemu/base/ManagedDescriptor.hpp"
#include "aemu/base/files/Stream.h"
#include "render-utils/Renderer.h"
+#include "snapshot/LazySnapshotObj.h"
// From ANGLE "src/common/angleutils.h"
#define GL_BGR10_A2_ANGLEX 0x6AF9
@@ -45,54 +46,60 @@
// related things:
//
// - Every gralloc native buffer with HW read or write requirements will
-// allocate a host ColorBufferGl instance. When gralloc_lock() is called,
-// the guest will use ColorBufferGl::readPixels() to read the current content
+// allocate a host ColorBuffer instance. When gralloc_lock() is called,
+// the guest will use ColorBuffer::readPixels() to read the current content
// of the buffer. When gralloc_unlock() is later called, it will call
-// ColorBufferGl::subUpdate() to send the updated pixels.
+// ColorBuffer::subUpdate() to send the updated pixels.
//
// - Every guest window EGLSurface is implemented by a host PBuffer
-// (see WindowSurface.h) that can have a ColorBufferGl instance attached to
+// (see WindowSurface.h) that can have a ColorBuffer instance attached to
// it (through WindowSurface::attachColorBuffer()). When such an attachment
// exists, WindowSurface::flushColorBuffer() will copy the PBuffer's
-// pixel data into the ColorBufferGl. The latter can then be displayed
-// in the client's UI sub-window with ColorBufferGl::post().
+// pixel data into the ColorBuffer. The latter can then be displayed
+// in the client's UI sub-window with ColorBuffer::post().
//
// - Guest EGLImages are implemented as native gralloc buffers too.
// The guest glEGLImageTargetTexture2DOES() implementations will end up
-// calling ColorBufferGl::bindToTexture() to bind the current context's
+// calling ColorBuffer::bindToTexture() to bind the current context's
// GL_TEXTURE_2D to the buffer. Similarly, the guest versions of
// glEGLImageTargetRenderbufferStorageOES() will end up calling
-// ColorBufferGl::bindToRenderbuffer().
+// ColorBuffer::bindToRenderbuffer().
//
// This forces the implementation to use a host EGLImage to implement each
-// ColorBufferGl.
+// ColorBuffer.
//
// As an additional twist.
-namespace gfxstream {
-
-class ColorBufferGl {
+class ColorBuffer :
+ public android::snapshot::LazySnapshotObj<ColorBuffer> {
public:
- // Create a new ColorBufferGl instance.
- // |display| is the host EGLDisplay handle.
- // |width| and |height| are the buffer's dimensions in pixels.
- // |internalFormat| is the internal OpenGL pixel format to use, valid
+ // Create a new ColorBuffer instance.
+ // |p_display| is the host EGLDisplay handle.
+ // |p_width| and |p_height| are the buffer's dimensions in pixels.
+ // |p_internalFormat| is the internal OpenGL pixel format to use, valid
// values
// are: GL_RGB, GL_RGB565, GL_RGBA, GL_RGB5_A1_OES and GL_RGBA4_OES.
// Implementation is free to use something else though.
- // |frameworkFormat| specifies the original format of the guest
- // color buffer so that we know how to convert to |internalFormat|,
- // if necessary (otherwise, frameworkFormat ==
+ // |p_frameworkFormat| specifies the original format of the guest
+ // color buffer so that we know how to convert to |p_internalFormat|,
+ // if necessary (otherwise, p_frameworkFormat ==
// FRAMEWORK_FORMAT_GL_COMPATIBLE).
// It is assumed underlying EGL has EGL_KHR_gl_texture_2D_image.
// Returns NULL on failure.
- // |fastBlitSupported|: whether or not this ColorBufferGl can be
+ // |fastBlitSupported|: whether or not this ColorBuffer can be
// blitted and posted to swapchain without context switches.
- static std::unique_ptr<ColorBufferGl> create(EGLDisplay display, int width, int height,
- GLint internalFormat,
- FrameworkFormat frameworkFormat, HandleType handle,
- ContextHelper* helper, TextureDraw* textureDraw,
- bool fastBlitSupported);
+ // |vulkanOnly|: whether or not the guest interacts entirely with Vulkan
+ // and does not use the GL based API.
+ static ColorBuffer* create(EGLDisplay p_display,
+ int p_width,
+ int p_height,
+ GLint p_internalFormat,
+ FrameworkFormat p_frameworkFormat,
+ HandleType hndl,
+ ContextHelper* helper,
+ TextureDraw* textureDraw,
+ bool fastBlitSupported,
+ bool vulkanOnly = false);
// Sometimes things happen and we need to reformat the GL texture
// used. This function replaces the format of the underlying texture
@@ -100,14 +107,14 @@
void reformat(GLint internalformat, GLenum type);
// Destructor.
- ~ColorBufferGl();
+ ~ColorBuffer();
- // Return ColorBufferGl width and height in pixels
+ // Return ColorBuffer width and height in pixels
GLuint getWidth() const { return m_width; }
GLuint getHeight() const { return m_height; }
GLint getInternalFormat() const { return m_internalFormat; }
- // Read the ColorBufferGl instance's pixel values into host memory.
+ // Read the ColorBuffer instance's pixel values into host memory.
void readPixels(int x,
int y,
int width,
@@ -119,7 +126,7 @@
// to the size of width x height, then clipping a |rect| from the
// screen defined by width x height.
void readPixelsScaled(int width, int height, GLenum p_format, GLenum p_type, int skinRotation,
- emugl::Rect rect, void* pixels);
+ void* pixels, emugl::Rect rect);
// Read cached YUV pixel values into host memory.
void readPixelsYUVCached(int x,
@@ -129,18 +136,23 @@
void* pixels,
uint32_t pixels_size);
- void swapYUVTextures(FrameworkFormat texture_type, GLuint* textures);
+ void swapYUVTextures(uint32_t texture_type, uint32_t* textures);
- // Update the ColorBufferGl instance's pixel values from host memory.
+ // Update the ColorBuffer instance's pixel values from host memory.
// |p_format / p_type| are the desired OpenGL color buffer format
// and data type.
// Otherwise, subUpdate() will explicitly convert |pixels|
// to be in |p_format|.
- void subUpdate(int x, int y, int width, int height, GLenum p_format, GLenum p_type,
- const void* pixels);
+ void subUpdate(int x,
+ int y,
+ int width,
+ int height,
+ GLenum p_format,
+ GLenum p_type,
+ void* pixels);
void subUpdateFromFrameworkFormat(int x, int y, int width, int height,
FrameworkFormat fwkFormat, GLenum p_format, GLenum p_type,
- const void* pixels);
+ void* pixels);
// Completely replaces contents, assuming that |pixels| is a buffer
// that is allocated and filled with the same format.
@@ -150,7 +162,7 @@
// If the framework format is YUV, it will read back as raw YUV data.
bool readContents(size_t* numBytes, void* pixels);
- // Draw a ColorBufferGl instance, i.e. blit it to the current guest
+ // Draw a ColorBuffer instance, i.e. blit it to the current guest
// framebuffer object / window surface. This doesn't display anything.
bool draw();
@@ -162,38 +174,40 @@
// |rotation| is the rotation angle in degrees, clockwise in the GL
// coordinate space.
bool post(GLuint tex, float rotation, float dx, float dy);
- // Post this ColorBufferGl to the host native sub-window and apply
+ // Post this ColorBuffer to the host native sub-window and apply
// the device screen overlay (if there is one).
// |rotation| is the rotation angle in degrees, clockwise in the GL
// coordinate space.
- bool postViewportScaledWithOverlay(float rotation, float dx, float dy);
+ bool postWithOverlay(float rotation, float dx, float dy);
- // Bind the current context's EGL_TEXTURE_2D texture to this ColorBufferGl's
+ // Bind the current context's EGL_TEXTURE_2D texture to this ColorBuffer's
// EGLImage. This is intended to implement glEGLImageTargetTexture2DOES()
// for all GLES versions.
bool bindToTexture();
bool bindToTexture2();
// Bind the current context's EGL_RENDERBUFFER_OES render buffer to this
- // ColorBufferGl's EGLImage. This is intended to implement
+ // ColorBuffer's EGLImage. This is intended to implement
// glEGLImageTargetRenderbufferStorageOES() for all GLES versions.
bool bindToRenderbuffer();
// Copy the content of the current context's read surface to this
- // ColorBufferGl. This is used from WindowSurface::flushColorBuffer().
+ // ColorBuffer. This is used from WindowSurface::flushColorBuffer().
// Return true on success, false on failure (e.g. no current context).
bool blitFromCurrentReadBuffer();
- // Read the content of the whole ColorBufferGl as 32-bit RGBA pixels.
+ // Read the content of the whole ColorBuffer as 32-bit RGBA pixels.
// |img| must be a buffer large enough (i.e. width * height * 4).
void readback(unsigned char* img, bool readbackBgra = false);
// readback() but async (to the specified |buffer|)
void readbackAsync(GLuint buffer, bool readbackBgra = false);
void onSave(android::base::Stream* stream);
- static std::unique_ptr<ColorBufferGl> onLoad(android::base::Stream* stream,
- EGLDisplay p_display, ContextHelper* helper,
- TextureDraw* textureDraw, bool fastBlitSupported);
+ static ColorBuffer* onLoad(android::base::Stream* stream,
+ EGLDisplay p_display,
+ ContextHelper* helper,
+ TextureDraw* textureDraw,
+ bool fastBlitSupported);
HandleType getHndl() const;
@@ -203,18 +217,21 @@
std::unique_ptr<BorrowedImageInfo> getBorrowedImageInfo();
- // ColorBufferGl backing change methods
+ // ColorBuffer backing change methods
//
// Change to opaque fd or opaque win32 handle-backed VkDeviceMemory
// via GL_EXT_memory_objects
bool importMemory(android::base::ManagedDescriptor externalDescriptor, uint64_t size,
- bool dedicated, bool linearTiling);
+ bool dedicated, bool linearTiling, bool vulkanOnly);
// Change to EGL native pixmap
bool importEglNativePixmap(void* pixmap, bool preserveContent);
// Change to some other native EGL image. nativeEglImage must not have
// been created from our s_egl.eglCreateImage.
bool importEglImage(void* nativeEglImage, bool preserveContent);
+ void setInUse(bool inUse);
+ bool isInUse() const { return m_inUse; }
+
void setSync(bool debug = false);
void waitSync(bool debug = false);
void setDisplay(uint32_t displayId) { m_displayId = displayId; }
@@ -225,24 +242,24 @@
void restore();
private:
- ColorBufferGl(EGLDisplay display, HandleType hndl, GLuint width, GLuint height,
- ContextHelper* helper, TextureDraw* textureDraw);
- // Helper function to get contents.
- std::vector<uint8_t> getContents();
- // Helper function to clear current EGL image.
- void clearStorage();
- // Helper function to bind EGL image as texture. Assumes storage cleared.
- void restoreEglImage(EGLImageKHR image);
- // Helper function that does the above two operations in one go.
- void rebindEglImage(EGLImageKHR image, bool preserveContent);
+ ColorBuffer(EGLDisplay display, HandleType hndl, ContextHelper* helper,
+ TextureDraw* textureDraw);
+ // Helper function to get contents.
+ std::vector<uint8_t> getContents();
+ // Helper function to clear current EGL image.
+ void clearStorage();
+ // Helper function to bind EGL image as texture. Assumes storage cleared.
+ void restoreEglImage(EGLImageKHR image);
+ // Helper function that does the above two operations in one go.
+ void rebindEglImage(EGLImageKHR image, bool preserveContent);
private:
GLuint m_tex = 0;
GLuint m_blitTex = 0;
EGLImageKHR m_eglImage = nullptr;
EGLImageKHR m_blitEGLImage = nullptr;
- const GLuint m_width = 0;
- const GLuint m_height = 0;
+ GLuint m_width = 0;
+ GLuint m_height = 0;
GLuint m_fbo = 0;
GLint m_internalFormat = 0;
GLint m_sizedInternalFormat = 0;
@@ -289,6 +306,21 @@
bool m_BRSwizzle = false;
};
-typedef std::shared_ptr<ColorBufferGl> ColorBufferGlPtr;
+typedef std::shared_ptr<ColorBuffer> ColorBufferPtr;
-} // namespace gfxstream
+struct ColorBufferRef {
+ ColorBufferPtr cb;
+ uint32_t refcount; // number of client-side references
+
+ // Tracks whether opened at least once. In O+,
+ // color buffers can be created/closed immediately,
+ // but then registered (opened) afterwards.
+ bool opened;
+
+ // Tracks the time when this buffer got a close request while not being
+ // opened yet.
+ uint64_t closedTs;
+};
+
+typedef std::unordered_map<HandleType, ColorBufferRef> ColorBufferMap;
+typedef std::unordered_multiset<HandleType> ColorBufferSet;
diff --git a/stream-servers/gl/DisplayGl.cpp b/stream-servers/gl/DisplayGl.cpp
index 915394f..86c9f49 100644
--- a/stream-servers/gl/DisplayGl.cpp
+++ b/stream-servers/gl/DisplayGl.cpp
@@ -53,14 +53,16 @@
mTextureDraw->prepareForDrawLayer();
hasDrawLayer = true;
}
- layer.colorBuffer->glOpPostLayer(*layer.layerOptions, post.frameWidth,
- post.frameHeight);
+ layer.colorBuffer->postLayer(*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);
+ layer.colorBuffer->postWithOverlay(layer.overlayOptions->rotation,
+ layer.overlayOptions->dx,
+ layer.overlayOptions->dy);
}
}
if (hasDrawLayer) {
diff --git a/stream-servers/gl/DisplayGl.h b/stream-servers/gl/DisplayGl.h
index a82f520..c421481 100644
--- a/stream-servers/gl/DisplayGl.h
+++ b/stream-servers/gl/DisplayGl.h
@@ -14,17 +14,17 @@
#pragma once
+#include <atomic>
+#include <future>
+
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
-#include <atomic>
-#include <future>
-
-#include "ColorBuffer.h"
#include "Display.h"
#include "Hwc2.h"
+#include "gl/ColorBufferGl.h"
class DisplayGl : public gfxstream::Display {
public:
diff --git a/stream-servers/gl/EmulatedEglWindowSurface.cpp b/stream-servers/gl/EmulatedEglWindowSurface.cpp
index 426b3a4..9899aaa 100644
--- a/stream-servers/gl/EmulatedEglWindowSurface.cpp
+++ b/stream-servers/gl/EmulatedEglWindowSurface.cpp
@@ -122,7 +122,7 @@
}
}
- mAttachedColorBuffer->glOpBlitFromCurrentReadBuffer();
+ mAttachedColorBuffer->blitFromCurrentReadBuffer();
if (needToSet) {
// restore current context/surface
diff --git a/stream-servers/gl/EmulatedEglWindowSurface.h b/stream-servers/gl/EmulatedEglWindowSurface.h
index a3a0108..779a4c1 100644
--- a/stream-servers/gl/EmulatedEglWindowSurface.h
+++ b/stream-servers/gl/EmulatedEglWindowSurface.h
@@ -16,14 +16,13 @@
#pragma once
+#include <memory>
+#include <unordered_set>
+#include <unordered_map>
+
#include <EGL/egl.h>
#include <GLES/gl.h>
-#include <memory>
-#include <unordered_map>
-#include <unordered_set>
-
-#include "ColorBuffer.h"
#include "Handle.h"
#include "gl/ColorBufferGl.h"
#include "gl/EmulatedEglContext.h"
diff --git a/stream-servers/gl/EmulationGl.cpp b/stream-servers/gl/EmulationGl.cpp
index aa72329..86fcbe4 100644
--- a/stream-servers/gl/EmulationGl.cpp
+++ b/stream-servers/gl/EmulationGl.cpp
@@ -594,29 +594,6 @@
}
}
-ContextHelper* EmulationGl::getColorBufferContextHelper() {
- if (!mPbufferSurface) {
- return nullptr;
- }
-
- const auto* surfaceGl = static_cast<const DisplaySurfaceGl*>(mPbufferSurface->getImpl());
- return surfaceGl->getContextHelper();
-}
-
-std::unique_ptr<ColorBufferGl> EmulationGl::createColorBuffer(uint32_t width, uint32_t height,
- GLenum internalFormat,
- FrameworkFormat frameworkFormat,
- HandleType handle) {
- return ColorBufferGl::create(mEglDisplay, width, height, internalFormat, frameworkFormat,
- handle, getColorBufferContextHelper(), mTextureDraw.get(),
- isFastBlitSupported());
-}
-
-std::unique_ptr<ColorBufferGl> EmulationGl::loadColorBuffer(android::base::Stream* stream) {
- return ColorBufferGl::onLoad(stream, mEglDisplay, getColorBufferContextHelper(),
- mTextureDraw.get(), isFastBlitSupported());
-}
-
std::unique_ptr<EmulatedEglContext> EmulationGl::createEmulatedEglContext(
uint32_t emulatedEglConfigIndex,
const EmulatedEglContext* sharedContext,
diff --git a/stream-servers/gl/EmulationGl.h b/stream-servers/gl/EmulationGl.h
index 6146561..65168ca 100644
--- a/stream-servers/gl/EmulationGl.h
+++ b/stream-servers/gl/EmulationGl.h
@@ -14,24 +14,24 @@
#pragma once
+#include <array>
+#include <memory>
+#include <string>
+#include <optional>
+#include <unordered_set>
+
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES/gl.h>
#include <GLES3/gl3.h>
-#include <array>
-#include <memory>
-#include <optional>
-#include <string>
-#include <unordered_set>
-
-#include "ColorBufferGl.h"
+#include "ContextHelper.h"
#include "Compositor.h"
#include "CompositorGl.h"
-#include "ContextHelper.h"
#include "Display.h"
#include "DisplayGl.h"
#include "DisplaySurface.h"
+#include "EmulatedEglContext.h"
#include "EmulatedEglConfig.h"
#include "EmulatedEglContext.h"
#include "EmulatedEglFenceSync.h"
@@ -40,7 +40,6 @@
#include "OpenGLESDispatch/GLESv2Dispatch.h"
#include "ReadbackWorkerGl.h"
#include "TextureDraw.h"
-#include "aemu/base/files/Stream.h"
#define EGL_NO_CONFIG ((EGLConfig)0)
@@ -86,18 +85,14 @@
ReadbackWorkerGl* getReadbackWorker() { return mReadbackWorkerGl.get(); }
+ // TODO(b/233939967): Remove after adding ColorBufferGl and EmulationGl::createColorBuffer().
+ TextureDraw* getTextureDraw() const { return mTextureDraw.get(); }
+
using GlesUuid = std::array<uint8_t, GL_UUID_SIZE_EXT>;
const std::optional<GlesUuid> getGlesDeviceUuid() const { return mGlesDeviceUuid; }
void setUseBoundSurfaceContextForDisplay(bool use);
- std::unique_ptr<ColorBufferGl> createColorBuffer(uint32_t width, uint32_t height,
- GLenum internalFormat,
- FrameworkFormat frameworkFormat,
- HandleType handle);
-
- std::unique_ptr<ColorBufferGl> loadColorBuffer(android::base::Stream* stream);
-
std::unique_ptr<EmulatedEglContext> createEmulatedEglContext(
uint32_t emulatedEglConfigIndex,
const EmulatedEglContext* shareContext,
@@ -133,8 +128,6 @@
EmulationGl() = default;
- ContextHelper* getColorBufferContextHelper();
-
EGLDisplay mEglDisplay = EGL_NO_DISPLAY;
EGLint mEglVersionMajor = 0;
EGLint mEglVersionMinor = 0;
diff --git a/stream-servers/gl/ReadbackWorkerGl.cpp b/stream-servers/gl/ReadbackWorkerGl.cpp
index 426f86b..41a0c93 100644
--- a/stream-servers/gl/ReadbackWorkerGl.cpp
+++ b/stream-servers/gl/ReadbackWorkerGl.cpp
@@ -17,7 +17,6 @@
#include <string.h>
-#include "ColorBuffer.h"
#include "ContextHelper.h"
#include "OpenGLESDispatch/DispatchTables.h"
#include "OpenGLESDispatch/EGLDispatch.h"
@@ -166,7 +165,7 @@
r.m_readbackCount++;
r.mPrevReadPixelsIndex = readAt;
- cb->glOpReadbackAsync(r.mBuffers[readAt], readbackBgra);
+ cb->readbackAsync(r.mBuffers[readAt], readbackBgra);
// It's possible to post callback before any of the async readbacks
// have written any data yet, which results in a black frame. Safer
diff --git a/stream-servers/gl/YUVConverter.cpp b/stream-servers/gl/YUVConverter.cpp
index d06f768..f9735a0 100644
--- a/stream-servers/gl/YUVConverter.cpp
+++ b/stream-servers/gl/YUVConverter.cpp
@@ -461,8 +461,7 @@
s_gles2.glActiveTexture(GL_TEXTURE0);
}
-static void readYUVTex(GLuint tex, FrameworkFormat format, YUVPlane plane, void* pixels,
- uint32_t pixelsStride) {
+static void readYUVTex(GLuint tex, FrameworkFormat format, YUVPlane plane, void* pixels) {
YUV_DEBUG_LOG("format%d plane:%d pixels:%p", format, plane, pixels);
GLuint prevTexture = 0;
@@ -471,10 +470,6 @@
GLint prevAlignment = 0;
s_gles2.glGetIntegerv(GL_PACK_ALIGNMENT, &prevAlignment);
s_gles2.glPixelStorei(GL_PACK_ALIGNMENT, 1);
- GLint prevStride = 0;
- s_gles2.glGetIntegerv(GL_PACK_ROW_LENGTH, &prevStride);
- s_gles2.glPixelStorei(GL_PACK_ROW_LENGTH, pixelsStride);
-
const GLenum pixelFormat = getGlPixelFormat(format, plane);
const GLenum pixelType = getGlPixelType(format, plane);
if (s_gles2.glGetTexImage) {
@@ -483,7 +478,6 @@
YUV_DEBUG_LOG("empty glGetTexImage");
}
- s_gles2.glPixelStorei(GL_PACK_ROW_LENGTH, prevStride);
s_gles2.glPixelStorei(GL_PACK_ALIGNMENT, prevAlignment);
s_gles2.glBindTexture(GL_TEXTURE_2D, prevTexture);
}
@@ -858,11 +852,10 @@
&vWidth, &vHeight, &vOffsetBytes, &vStridePixels, &vStrideBytes);
if (isInterleaved(mFormat)) {
- readYUVTex(mTextureV, mFormat, YUVPlane::UV, pixels + std::min(uOffsetBytes, vOffsetBytes),
- uStridePixels);
+ readYUVTex(mTextureV, mFormat, YUVPlane::UV, pixels + std::min(uOffsetBytes, vOffsetBytes));
} else {
- readYUVTex(mTextureU, mFormat, YUVPlane::U, pixels + uOffsetBytes, uStridePixels);
- readYUVTex(mTextureV, mFormat, YUVPlane::V, pixels + vOffsetBytes, vStridePixels);
+ readYUVTex(mTextureU, mFormat, YUVPlane::U, pixels + uOffsetBytes);
+ readYUVTex(mTextureV, mFormat, YUVPlane::V, pixels + vOffsetBytes);
}
if (mFormat == FRAMEWORK_FORMAT_NV12 && mColorBufferFormat == FRAMEWORK_FORMAT_YUV_420_888) {
@@ -870,10 +863,12 @@
}
// Read the Y plane last because so that we can use it as a scratch space.
- readYUVTex(mTextureY, mFormat, YUVPlane::Y, pixels + yOffsetBytes, yStridePixels);
+ readYUVTex(mTextureY, mFormat, YUVPlane::Y, pixels + yOffsetBytes);
}
-void YUVConverter::swapTextures(FrameworkFormat format, GLuint* textures) {
+void YUVConverter::swapTextures(uint32_t type, uint32_t* textures) {
+ FrameworkFormat format = static_cast<FrameworkFormat>(type);
+
if (isInterleaved(format)) {
std::swap(textures[0], mTextureY);
std::swap(textures[1], mTextureU);
diff --git a/stream-servers/gl/YUVConverter.h b/stream-servers/gl/YUVConverter.h
index 23dde61..8cddee1 100644
--- a/stream-servers/gl/YUVConverter.h
+++ b/stream-servers/gl/YUVConverter.h
@@ -71,7 +71,7 @@
// if size mismatches, will read nothing.
void readPixels(uint8_t* pixels, uint32_t pixels_size);
- void swapTextures(FrameworkFormat type, GLuint* textures);
+ void swapTextures(uint32_t type, uint32_t* textures);
// public so other classes can call
static void createYUVGLTex(GLenum textureUnit,
diff --git a/stream-servers/tests/FrameBuffer_unittest.cpp b/stream-servers/tests/FrameBuffer_unittest.cpp
index 410986d..63915af 100644
--- a/stream-servers/tests/FrameBuffer_unittest.cpp
+++ b/stream-servers/tests/FrameBuffer_unittest.cpp
@@ -540,14 +540,14 @@
EXPECT_TRUE(mFb->isFastBlitSupported());
mFb->lock();
- EXPECT_EQ(mFb->isFastBlitSupported(), mFb->findColorBuffer(handle)->glOpIsFastBlitSupported());
+ EXPECT_EQ(mFb->isFastBlitSupported(), mFb->findColorBuffer(handle)->isFastBlitSupported());
mFb->unlock();
saveSnapshot();
loadSnapshot();
mFb->lock();
- EXPECT_EQ(mFb->isFastBlitSupported(), mFb->findColorBuffer(handle)->glOpIsFastBlitSupported());
+ EXPECT_EQ(mFb->isFastBlitSupported(), mFb->findColorBuffer(handle)->isFastBlitSupported());
mFb->unlock();
mFb->closeColorBuffer(handle);
diff --git a/stream-servers/vulkan/VkAndroidNativeBuffer.cpp b/stream-servers/vulkan/VkAndroidNativeBuffer.cpp
index 07a1666..096cc8c 100644
--- a/stream-servers/vulkan/VkAndroidNativeBuffer.cpp
+++ b/stream-servers/vulkan/VkAndroidNativeBuffer.cpp
@@ -511,6 +511,8 @@
// If we used the Vulkan image without copying it back
// to the CPU, reset the layout to PRESENT.
if (anbInfo->useVulkanNativeImage) {
+ fb->setColorBufferInUse(anbInfo->colorBufferHandle, true);
+
VkCommandBufferBeginInfo beginInfo = {
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
0,
@@ -759,6 +761,7 @@
if (anbInfo->useVulkanNativeImage) {
VK_ANB_DEBUG_OBJ(anbInfoPtr, "using native image, so use sync thread to wait");
+ fb->setColorBufferInUse(anbInfo->colorBufferHandle, false);
// Queue wait to sync thread with completion callback
// Pass anbInfo by value to get a ref
SyncThread::get()->triggerGeneral(