diff options
-rw-r--r-- | stream-servers/ColorBuffer.cpp | 13 | ||||
-rw-r--r-- | stream-servers/ColorBuffer.h | 22 | ||||
-rw-r--r-- | stream-servers/DisplayVk.cpp | 113 | ||||
-rw-r--r-- | stream-servers/DisplayVk.h | 48 | ||||
-rw-r--r-- | stream-servers/FrameBuffer.cpp | 54 | ||||
-rw-r--r-- | stream-servers/FrameBuffer.h | 196 | ||||
-rw-r--r-- | stream-servers/tests/DisplayVk_unittest.cpp | 33 |
7 files changed, 235 insertions, 244 deletions
diff --git a/stream-servers/ColorBuffer.cpp b/stream-servers/ColorBuffer.cpp index f12f2da1..24d17ae0 100644 --- a/stream-servers/ColorBuffer.cpp +++ b/stream-servers/ColorBuffer.cpp @@ -299,8 +299,6 @@ ColorBuffer::ColorBuffer(EGLDisplay display, HandleType hndl, Helper* helper) ColorBuffer::~ColorBuffer() { RecursiveScopedHelperContext context(m_helper); - m_helper->releaseDisplayImport(getHndl()); - if (m_blitEGLImage) { s_egl.eglDestroyImageKHR(m_display, m_blitEGLImage); } @@ -935,15 +933,14 @@ void ColorBuffer::postLayer(ComposeLayer* l, int frameWidth, int frameHeight) { bool ColorBuffer::importMemory( #ifdef _WIN32 - void* handle, + void* handle, #else - int handle, + int handle, #endif - uint64_t size, - bool dedicated, - bool linearTiling, - bool vulkanOnly) { + uint64_t size, bool dedicated, bool linearTiling, bool vulkanOnly, + std::shared_ptr<DisplayVk::DisplayBufferInfo> displayBufferVk) { RecursiveScopedHelperContext context(m_helper); + m_displayBufferVk = std::move(displayBufferVk); s_gles2.glCreateMemoryObjectsEXT(1, &m_memoryObject); if (dedicated) { static const GLint DEDICATED_FLAG = GL_TRUE; diff --git a/stream-servers/ColorBuffer.h b/stream-servers/ColorBuffer.h index 6249b776..9d4eb91d 100644 --- a/stream-servers/ColorBuffer.h +++ b/stream-servers/ColorBuffer.h @@ -22,12 +22,13 @@ #include <GLES3/gl3.h> #include "base/Stream.h" // #include "android/skin/rect.h" -#include "snapshot/LazySnapshotObj.h" +#include <memory> + +#include "DisplayVk.h" #include "FrameworkFormats.h" #include "Hwc2.h" #include "RenderContext.h" - -#include <memory> +#include "snapshot/LazySnapshotObj.h" class TextureDraw; class TextureResize; @@ -74,7 +75,6 @@ public: virtual void teardownContext() = 0; virtual TextureDraw* getTextureDraw() const = 0; virtual bool isBound() const = 0; - virtual void releaseDisplayImport(HandleType) = 0; }; // Helper class to use a ColorBuffer::Helper context. @@ -251,16 +251,19 @@ public: void postLayer(ComposeLayer* l, int frameWidth, int frameHeight); GLuint getTexture(); + const std::shared_ptr<DisplayVk::DisplayBufferInfo>& getDisplayBufferVk() + const { + return m_displayBufferVk; + }; + bool importMemory( #ifdef _WIN32 void* handle, #else int handle, #endif - uint64_t size, - bool dedicated, - bool linearTiling, - bool vulkanOnly); + uint64_t size, bool dedicated, bool linearTiling, bool vulkanOnly, + std::shared_ptr<DisplayVk::DisplayBufferInfo> displayBufferVk); void setInUse(bool inUse); bool isInUse() const { return m_inUse; } @@ -320,6 +323,9 @@ private: GLuint m_buf = 0; uint32_t m_displayId = 0; bool m_BRSwizzle = false; + // Won't share with others so that m_displayBufferVk lives shorter than this + // ColorBuffer. + std::shared_ptr<DisplayVk::DisplayBufferInfo> m_displayBufferVk; }; typedef std::shared_ptr<ColorBuffer> ColorBufferPtr; diff --git a/stream-servers/DisplayVk.cpp b/stream-servers/DisplayVk.cpp index f10a53b0..78e50461 100644 --- a/stream-servers/DisplayVk.cpp +++ b/stream-servers/DisplayVk.cpp @@ -1,11 +1,11 @@ #include "DisplayVk.h" -#include "ErrorLog.h" -#include "NativeSubWindow.h" - #include <glm/glm.hpp> #include <glm/gtx/matrix_transform_2d.hpp> +#include "ErrorLog.h" +#include "NativeSubWindow.h" + DisplayVk::DisplayVk(const goldfish_vk::VulkanDispatch &vk, VkPhysicalDevice vkPhysicalDevice, uint32_t swapChainQueueFamilyIndex, @@ -109,55 +109,21 @@ void DisplayVk::bindToSurface(VkSurfaceKHR surface, uint32_t width, m_surfaceState = std::move(surfaceState); } -void DisplayVk::importVkImage(HandleType id, VkImage image, VkFormat format, - uint32_t width, uint32_t height) { - if (m_colorBuffers.find(id) != m_colorBuffers.end()) { - ERR("%s(%s:%d): DisplayVk can't import VkImage with duplicate id = " - "%" PRIu64 ".\n", - __FUNCTION__, __FILE__, static_cast<int>(__LINE__), - static_cast<uint64_t>(id)); - ::abort(); - } - ColorBufferInfo cbInfo = {}; - cbInfo.m_width = width; - cbInfo.m_height = height; - cbInfo.m_vkFormat = format; - - VkImageViewCreateInfo imageViewCi = {}; - imageViewCi.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - imageViewCi.image = image; - imageViewCi.viewType = VK_IMAGE_VIEW_TYPE_2D; - imageViewCi.format = format; - imageViewCi.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; - imageViewCi.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; - imageViewCi.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; - imageViewCi.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; - imageViewCi.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - imageViewCi.subresourceRange.baseMipLevel = 0; - imageViewCi.subresourceRange.levelCount = 1; - imageViewCi.subresourceRange.baseArrayLayer = 0; - imageViewCi.subresourceRange.layerCount = 1; - VK_CHECK(m_vk.vkCreateImageView(m_vkDevice, &imageViewCi, nullptr, - &cbInfo.m_vkImageView)); - m_colorBuffers.emplace(id, cbInfo); +std::shared_ptr<DisplayVk::DisplayBufferInfo> DisplayVk::createDisplayBuffer( + VkImage image, VkFormat format, uint32_t width, uint32_t height) { + return std::shared_ptr<DisplayBufferInfo>( + new DisplayBufferInfo(m_vk, m_vkDevice, width, height, format, image)); } -void DisplayVk::releaseImport(HandleType id) { - auto it = m_colorBuffers.find(id); - if (it == m_colorBuffers.end()) { - return; - } - m_vk.vkDestroyImageView(m_vkDevice, it->second.m_vkImageView, nullptr); - m_colorBuffers.erase(it); -} - -void DisplayVk::post(HandleType id) { +void DisplayVk::post( + const std::shared_ptr<DisplayBufferInfo> &displayBufferPtr) { if (m_swapChainStateVk == nullptr || m_compositorVk == nullptr) { ERR("%s(%s:%d): Haven't bound to a surface, can't post color buffer.\n", __FUNCTION__, __FILE__, static_cast<int>(__LINE__)); return; } - const auto &surfaceState = *m_surfaceState; + auto &surfaceState = *m_surfaceState; + const auto &db = *displayBufferPtr; VK_CHECK(m_vk.vkWaitForFences(m_vkDevice, 1, &m_frameDrawCompleteFence, VK_TRUE, UINT64_MAX)); @@ -165,26 +131,26 @@ void DisplayVk::post(HandleType id) { VK_CHECK(m_vk.vkAcquireNextImageKHR( m_vkDevice, m_swapChainStateVk->getSwapChain(), UINT64_MAX, m_imageReadySem, VK_NULL_HANDLE, &imageIndex)); - if (!surfaceState.m_prevColorBuffer.has_value() || - surfaceState.m_prevColorBuffer.value() != id) { - const auto &cb = m_colorBuffers.at(id); - if (!canComposite(cb.m_vkFormat)) { - ERR("%s(%s:%d): Can't composite the ColorBuffer(id = %" PRIu64 + auto maybePrevDisplayBuffer = surfaceState.m_prevDisplayBuffer.lock(); + if (!maybePrevDisplayBuffer || maybePrevDisplayBuffer != displayBufferPtr) { + if (!canComposite(db.m_vkFormat)) { + ERR("%s(%s:%d): Can't composite the DisplayBuffer(0x%" PRIxPTR "). The image(VkFormat = %" PRIu64 ") can be sampled from.\n", __FUNCTION__, __FILE__, static_cast<int>(__LINE__), - static_cast<uint64_t>(id), - static_cast<uint64_t>(cb.m_vkFormat)); + reinterpret_cast<uintptr_t>(displayBufferPtr.get()), + static_cast<uint64_t>(db.m_vkFormat)); return; } auto composition = std::make_unique<Composition>( - cb.m_vkImageView, m_compositionVkSampler, cb.m_width, cb.m_height); + db.m_vkImageView, m_compositionVkSampler, db.m_width, db.m_height); composition->m_transform = glm::scale(glm::mat3(1.0), glm::vec2(static_cast<float>(surfaceState.m_width) / - static_cast<float>(cb.m_width), + static_cast<float>(db.m_width), static_cast<float>(surfaceState.m_height) / - static_cast<float>(cb.m_height))); + static_cast<float>(db.m_height))); m_compositorVk->setComposition(imageIndex, std::move(composition)); + surfaceState.m_prevDisplayBuffer = displayBufferPtr; } auto cmdBuff = m_compositorVk->getCommandBuffer(imageIndex); @@ -223,8 +189,41 @@ bool DisplayVk::canComposite(VkFormat format) { return it->second; } VkFormatProperties formatProps = {}; - m_vk.vkGetPhysicalDeviceFormatProperties(m_vkPhysicalDevice, format, &formatProps); - bool res = formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT; + m_vk.vkGetPhysicalDeviceFormatProperties(m_vkPhysicalDevice, format, + &formatProps); + bool res = + formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT; m_canComposite.emplace(format, res); return res; +} + +DisplayVk::DisplayBufferInfo::DisplayBufferInfo( + const goldfish_vk::VulkanDispatch &vk, VkDevice vkDevice, uint32_t width, + uint32_t height, VkFormat format, VkImage image) + : m_vk(vk), + m_vkDevice(vkDevice), + m_width(width), + m_height(height), + m_vkFormat(format), + m_vkImageView(VK_NULL_HANDLE) { + VkImageViewCreateInfo imageViewCi = {}; + imageViewCi.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + imageViewCi.image = image; + imageViewCi.viewType = VK_IMAGE_VIEW_TYPE_2D; + imageViewCi.format = format; + imageViewCi.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; + imageViewCi.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; + imageViewCi.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; + imageViewCi.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; + imageViewCi.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + imageViewCi.subresourceRange.baseMipLevel = 0; + imageViewCi.subresourceRange.levelCount = 1; + imageViewCi.subresourceRange.baseArrayLayer = 0; + imageViewCi.subresourceRange.layerCount = 1; + VK_CHECK(m_vk.vkCreateImageView(m_vkDevice, &imageViewCi, nullptr, + &m_vkImageView)); +} + +DisplayVk::DisplayBufferInfo::~DisplayBufferInfo() { + m_vk.vkDestroyImageView(m_vkDevice, m_vkImageView, nullptr); }
\ No newline at end of file diff --git a/stream-servers/DisplayVk.h b/stream-servers/DisplayVk.h index 05dae479..88e86c20 100644 --- a/stream-servers/DisplayVk.h +++ b/stream-servers/DisplayVk.h @@ -3,10 +3,8 @@ #include <functional> #include <memory> -#include <optional> #include <unordered_map> -#include "ColorBuffer.h" #include "CompositorVk.h" #include "RenderContext.h" #include "SwapChainStateVk.h" @@ -17,17 +15,39 @@ class DisplayVk { public: + class DisplayBufferInfo { + public: + ~DisplayBufferInfo(); + + private: + DisplayBufferInfo(const goldfish_vk::VulkanDispatch &, VkDevice, + uint32_t width, uint32_t height, VkFormat, VkImage); + + const goldfish_vk::VulkanDispatch &m_vk; + VkDevice m_vkDevice; + uint32_t m_width; + uint32_t m_height; + VkFormat m_vkFormat; + + VkImageView m_vkImageView; + + friend class DisplayVk; + }; DisplayVk(const goldfish_vk::VulkanDispatch &, VkPhysicalDevice, uint32_t swapChainQueueFamilyIndex, uint32_t compositorQueueFamilyIndex, VkDevice, VkQueue compositorVkQueue, VkQueue swapChainVkQueue); ~DisplayVk(); void bindToSurface(VkSurfaceKHR, uint32_t width, uint32_t height); - void importVkImage(HandleType id, VkImage, VkFormat, uint32_t width, - uint32_t height); - void releaseImport(HandleType id); - // To display a colorbuffer, first import it by calling importVkImage - void post(HandleType id); + // The caller is responsible to make sure the VkImage lives longer than the + // DisplayBufferInfo created here. However, given that DisplayBufferInfo + // lives in a shared_ptr, the potential lifetime of DisplayBufferInfo is + // aligned to DisplayVk when DisplayVk::m_surfaceState::m_prevDisplayBuffer + // is locked and upgraded to a shared_ptr in DisplayVk::post. + std::shared_ptr<DisplayBufferInfo> createDisplayBuffer(VkImage, VkFormat, + uint32_t width, + uint32_t height); + void post(const std::shared_ptr<DisplayBufferInfo> &); private: bool canComposite(VkFormat); @@ -45,23 +65,13 @@ class DisplayVk { VkSemaphore m_imageReadySem; VkSemaphore m_frameDrawCompleteSem; - struct ColorBufferInfo { - uint32_t m_width; - uint32_t m_height; - VkFormat m_vkFormat; - VkImageView m_vkImageView; - }; - // This map won't automatically relaase all the created VkImageView. The - // client is responsible for calling releaseImport on all imported ids - // before this object is released. - std::unordered_map<HandleType, ColorBufferInfo> m_colorBuffers; - std::unique_ptr<SwapChainStateVk> m_swapChainStateVk; std::unique_ptr<CompositorVk> m_compositorVk; struct SurfaceState { uint32_t m_width = 0; uint32_t m_height = 0; - std::optional<HandleType> m_prevColorBuffer = std::nullopt; + std::weak_ptr<DisplayBufferInfo> m_prevDisplayBuffer = + std::weak_ptr<DisplayBufferInfo>(); }; std::unique_ptr<SurfaceState> m_surfaceState; std::unordered_map<VkFormat, bool> m_canComposite; diff --git a/stream-servers/FrameBuffer.cpp b/stream-servers/FrameBuffer.cpp index 06b384da..d410cd52 100644 --- a/stream-servers/FrameBuffer.cpp +++ b/stream-servers/FrameBuffer.cpp @@ -59,7 +59,7 @@ typedef ColorBuffer::RecursiveScopedHelperContext ScopedBind; // to a FrameBuffer instance. class ColorBufferHelper : public ColorBuffer::Helper { public: - ColorBufferHelper(FrameBuffer* fb) : mFb(fb), mDisplayVk(nullptr) {} + ColorBufferHelper(FrameBuffer* fb) : mFb(fb) {} virtual bool setupContext() override { mIsBound = mFb->bind_locked(); @@ -77,17 +77,8 @@ class ColorBufferHelper : public ColorBuffer::Helper { virtual bool isBound() const override { return mIsBound; } - virtual void releaseDisplayImport(HandleType id) override { - if (mDisplayVk) { - mDisplayVk->releaseImport(id); - } - } - - void setDisplayVk(DisplayVk* displayVk) { mDisplayVk = displayVk; } - private: FrameBuffer* mFb; - DisplayVk* mDisplayVk; bool mIsBound = false; }; @@ -377,8 +368,6 @@ bool FrameBuffer::initialize(int width, int height, bool useSubWindow, *dispatch, emu->physdev, emu->queueFamilyIndex, emu->queueFamilyIndex, emu->device, emu->queue, emu->queue); fb->m_vkInstance = emu->instance; - static_cast<ColorBufferHelper*>(fb->m_colorBufferHelper) - ->setDisplayVk(fb->m_displayVk.get()); } } @@ -703,12 +692,14 @@ bool FrameBuffer::importMemoryToColorBuffer( } auto& cb = *c->second.cb; + std::shared_ptr<DisplayVk::DisplayBufferInfo> db = nullptr; if (m_displayVk != nullptr) { - m_displayVk->importVkImage(colorBufferHandle, image, format, - static_cast<uint32_t>(cb.getWidth()), - static_cast<uint32_t>(cb.getHeight())); + db = m_displayVk->createDisplayBuffer( + image, format, static_cast<uint32_t>(cb.getWidth()), + static_cast<uint32_t>(cb.getHeight())); } - return cb.importMemory(handle, size, dedicated, linearTiling, vulkanOnly); + return cb.importMemory(handle, size, dedicated, linearTiling, vulkanOnly, + std::move(db)); } void FrameBuffer::setColorBufferInUse( @@ -1232,6 +1223,7 @@ void FrameBuffer::createColorBufferWithHandle( // emugl::emugl_crash_reporter( // "FATAL: color buffer with handle %u already exists", // handle); + ::abort(); } createColorBufferWithHandleLocked( @@ -1270,7 +1262,8 @@ HandleType FrameBuffer::createColorBufferWithHandleLocked( // Explicitly set refcount to 1 to avoid the colorbuffer being added to // m_colorBufferDelayedCloseList in FrameBuffer::onLoad(). if (m_refCountPipeEnabled) { - m_colorbuffers[handle] = { std::move(cb), 1, false, 0 }; + m_colorbuffers.try_emplace( + handle, ColorBufferRef{std::move(cb), 1, false, 0}); } else { // Android master default api level is 1000 int apiLevel = 1000; @@ -1278,7 +1271,9 @@ HandleType FrameBuffer::createColorBufferWithHandleLocked( // pre-O and post-O use different color buffer memory management // logic if (apiLevel > 0 && apiLevel < 26) { - m_colorbuffers[handle] = {std::move(cb), 1, false, 0}; + m_colorbuffers.try_emplace( + handle, + ColorBufferRef{std::move(cb), 1, false, 0}); RenderThreadInfo* tInfo = RenderThreadInfo::get(); uint64_t puid = tInfo->m_puid; @@ -1287,7 +1282,9 @@ HandleType FrameBuffer::createColorBufferWithHandleLocked( } } else { - m_colorbuffers[handle] = {std::move(cb), 0, false, 0}; + m_colorbuffers.try_emplace( + handle, + ColorBufferRef{std::move(cb), 0, false, 0}); } } } else { @@ -2246,7 +2243,11 @@ RenderContextPtr FrameBuffer::getContext_locked(HandleType p_context) { } ColorBufferPtr FrameBuffer::getColorBuffer_locked(HandleType p_colorBuffer) { - return android::base::findOrDefault(m_colorbuffers, p_colorBuffer).cb; + auto i = m_colorbuffers.find(p_colorBuffer); + if (i == m_colorbuffers.end()) { + return nullptr; + } + return i->second.cb; } WindowSurfacePtr FrameBuffer::getWindowSurface_locked(HandleType p_windowsurface) { @@ -2466,14 +2467,14 @@ bool FrameBuffer::postImpl(HandleType p_colorbuffer, bool ret = false; ColorBufferMap::iterator c; - // TODO(kaiyili, b/179481815): make DisplayVk::post asynchronous. - if (m_displayVk != nullptr) { - m_displayVk->post(p_colorbuffer); + c = m_colorbuffers.find(p_colorbuffer); + if (c == m_colorbuffers.end()) { goto EXIT; } - c = m_colorbuffers.find(p_colorbuffer); - if (c == m_colorbuffers.end()) { + // TODO(kaiyili, b/179481815): make DisplayVk::post asynchronous. + if (m_displayVk != nullptr) { + m_displayVk->post(c->second.cb->getDisplayBufferVk()); goto EXIT; } @@ -3015,7 +3016,8 @@ bool FrameBuffer::onLoad(Stream* stream, if (refCount == 0) { m_colorBufferDelayedCloseList.push_back({closedTs, handle}); } - return { handle, { std::move(cb), refCount, opened, closedTs } }; + return {handle, ColorBufferRef{std::move(cb), refCount, opened, + closedTs}}; }); m_lastPostedColorBuffer = static_cast<HandleType>(stream->getBe32()); GL_LOG("Got lasted posted color buffer from snapshot"); diff --git a/stream-servers/FrameBuffer.h b/stream-servers/FrameBuffer.h index dfc1c5ef..6fc45a10 100644 --- a/stream-servers/FrameBuffer.h +++ b/stream-servers/FrameBuffer.h @@ -1,18 +1,18 @@ /* -* Copyright (C) 2011-2015 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. -*/ + * Copyright (C) 2011-2015 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. + */ #ifndef _LIBRENDER_FRAMEBUFFER_H #define _LIBRENDER_FRAMEBUFFER_H @@ -21,6 +21,7 @@ #include <functional> #include <map> +#include <memory> #include <unordered_map> #include <unordered_set> @@ -62,7 +63,8 @@ struct BufferRef { BufferPtr buffer; }; -typedef std::unordered_map<HandleType, std::pair<WindowSurfacePtr, HandleType> > WindowSurfaceMap; +typedef std::unordered_map<HandleType, std::pair<WindowSurfacePtr, HandleType>> + WindowSurfaceMap; typedef std::unordered_set<HandleType> WindowSurfaceSet; typedef std::unordered_map<uint64_t, WindowSurfaceSet> ProcOwnedWindowSurfaces; @@ -193,7 +195,7 @@ class FrameBuffer { // |version| specifies the GLES version as a GLESApi enum. // Return a new handle value, which will be 0 in case of error. HandleType createRenderContext(int p_config, HandleType p_share, - GLESApi version = GLESApi_CM); + GLESApi version = GLESApi_CM); // Create a new WindowSurface instance from this display instance. // |p_config| is the index of one of the configs returned by getConfigs(). @@ -210,16 +212,16 @@ class FrameBuffer { // list of valid values. Note that ColorBuffer instances are reference- // counted. Use openColorBuffer / closeColorBuffer to operate on the // internal count. - HandleType createColorBuffer( - int p_width, int p_height, GLenum p_internalFormat, - FrameworkFormat p_frameworkFormat); + HandleType createColorBuffer(int p_width, int p_height, + GLenum p_internalFormat, + FrameworkFormat p_frameworkFormat); // Variant of createColorBuffer except with a particular // handle already assigned. This is for use with // virtio-gpu's RESOURCE_CREATE ioctl. - void createColorBufferWithHandle( - int p_width, int p_height, GLenum p_internalFormat, - FrameworkFormat p_frameworkFormat, - HandleType handle); + void createColorBufferWithHandle(int p_width, int p_height, + GLenum p_internalFormat, + FrameworkFormat p_frameworkFormat, + HandleType handle); // Create a new data Buffer instance from this display instance. // The buffer will be backed by a VkBuffer and VkDeviceMemory (if Vulkan @@ -271,9 +273,8 @@ class FrameBuffer { // of the context, the draw surface and the read surface, respectively. // Returns true on success, false on failure. // Note: if all handle values are 0, this is an unbind operation. - bool bindContext(HandleType p_context, - HandleType p_drawSurface, - HandleType p_readSurface); + bool bindContext(HandleType p_context, HandleType p_drawSurface, + HandleType p_readSurface); // Return a render context pointer from its handle RenderContextPtr getContext_locked(HandleType p_context); @@ -289,14 +290,14 @@ class FrameBuffer { // |p_surface| is the target WindowSurface's handle value. // |p_colorbuffer| is the ColorBuffer handle value. // Returns true on success, false otherwise. - bool setWindowSurfaceColorBuffer( - HandleType p_surface, HandleType p_colorbuffer); + bool setWindowSurfaceColorBuffer(HandleType p_surface, + HandleType p_colorbuffer); // Copy the content of a WindowSurface's Pbuffer to its attached // ColorBuffer. See the documentation for WindowSurface::flushColorBuffer() // |p_surface| is the target WindowSurface's handle value. // Returns true on success, false on failure. - bool flushWindowSurfaceColorBuffer(HandleType p_surface); + bool flushWindowSurfaceColorBuffer(HandleType p_surface); // Retrieves the color buffer handle associated with |p_surface|. // Returns 0 if there is no such handle. @@ -307,15 +308,15 @@ class FrameBuffer { // glEGLImageTargetTexture2DOES() for all GLES versions. // |p_colorbuffer| is the ColorBuffer's handle value. // Returns true on success, false on failure. - bool bindColorBufferToTexture(HandleType p_colorbuffer); - bool bindColorBufferToTexture2(HandleType p_colorbuffer); + bool bindColorBufferToTexture(HandleType p_colorbuffer); + bool bindColorBufferToTexture2(HandleType p_colorbuffer); // Bind the current context's EGL_RENDERBUFFER_OES render buffer to this // ColorBuffer's EGLImage. This is intended to implement // glEGLImageTargetRenderbufferStorageOES() for all GLES versions. // |p_colorbuffer| is the ColorBuffer's handle value. // Returns true on success, false on failure. - bool bindColorBufferToRenderbuffer(HandleType p_colorbuffer); + bool bindColorBufferToRenderbuffer(HandleType p_colorbuffer); // Read the content of a given ColorBuffer into client memory. // |p_colorbuffer| is the ColorBuffer's handle value. Similar @@ -326,9 +327,8 @@ class FrameBuffer { // |type| is the type of pixel data, e.g. GL_UNSIGNED_BYTE. // |pixels| is the address of a caller-provided buffer that will be filled // with the pixel data. - void readColorBuffer(HandleType p_colorbuffer, - int x, int y, int width, int height, - GLenum format, GLenum type, void *pixels); + void readColorBuffer(HandleType p_colorbuffer, int x, int y, int width, + int height, GLenum format, GLenum type, void* pixels); // Read the content of a given YUV420_888 ColorBuffer into client memory. // |p_colorbuffer| is the ColorBuffer's handle value. Similar @@ -338,29 +338,19 @@ class FrameBuffer { // |pixels| is the address of a caller-provided buffer that will be filled // with the pixel data. // |pixles_size| is the size of buffer - void readColorBufferYUV(HandleType p_colorbuffer, - int x, int y, int width, int height, - void *pixels, uint32_t pixels_size); + void readColorBufferYUV(HandleType p_colorbuffer, int x, int y, int width, + int height, void* pixels, uint32_t pixels_size); // create a Y texture and a UV texture with width and height, the created // texture ids are stored in textures respectively - void createYUVTextures(uint32_t type, - uint32_t count, - int width, - int height, + void createYUVTextures(uint32_t type, uint32_t count, int width, int height, uint32_t* output); void destroyYUVTextures(uint32_t type, uint32_t count, uint32_t* textures); - void updateYUVTextures(uint32_t type, - uint32_t* textures, - void* privData, + void updateYUVTextures(uint32_t type, uint32_t* textures, void* privData, void* func); - void swapTexturesAndUpdateColorBuffer(uint32_t colorbufferhandle, - int x, - int y, - int width, - int height, - uint32_t format, - uint32_t type, + void swapTexturesAndUpdateColorBuffer(uint32_t colorbufferhandle, int x, + int y, int width, int height, + uint32_t format, uint32_t type, uint32_t texture_type, uint32_t* textures); @@ -369,23 +359,21 @@ class FrameBuffer { // to glReadPixels(), this can be a slow operation. // |x|, |y|, |width| and |height| are the position and dimensions of // a rectangle whose pixel values will be transfered to the GPU - // |format| indicates the format of the OpenGL buffer, e.g. GL_RGB or GL_RGBA. - // |frameworkFormat| indicates the format of the pixel data; if + // |format| indicates the format of the OpenGL buffer, e.g. GL_RGB or + // GL_RGBA. |frameworkFormat| indicates the format of the pixel data; if // FRAMEWORK_FORMAT_GL_COMPATIBLE, |format| (OpenGL format) is used. // Otherwise, explicit conversion to |format| is needed. // |type| is the type of pixel data, e.g. GL_UNSIGNED_BYTE. // |pixels| is the address of a buffer containing the new pixel data. // Returns true on success, false otherwise. - bool updateColorBuffer(HandleType p_colorbuffer, - int x, int y, int width, int height, - GLenum format, GLenum type, void *pixels); + bool updateColorBuffer(HandleType p_colorbuffer, int x, int y, int width, + int height, GLenum format, GLenum type, + void* pixels); // Replaces contents completely using the color buffer's current format, // with row length equal to width of a row in bytes. // The number of bytes is passed as a check. - bool replaceColorBufferContents( - HandleType p_colorbuffer, - const void *pixels, - size_t numBytes); + bool replaceColorBufferContents(HandleType p_colorbuffer, + const void* pixels, size_t numBytes); // Reads back the raw color buffer to |pixels| // if |pixels| is not null. // Always returns in |numBytes| how many bytes were @@ -394,14 +382,10 @@ class FrameBuffer { // fewer or more bytes cannot be specified. // If the framework format is YUV, it will read // back as raw YUV data. - bool readColorBufferContents( - HandleType p_colorbuffer, - size_t* numBytes, - void *pixels); - - bool getColorBufferInfo(HandleType p_colorbuffer, - int* width, - int* height, + bool readColorBufferContents(HandleType p_colorbuffer, size_t* numBytes, + void* pixels); + + bool getColorBufferInfo(HandleType p_colorbuffer, int* width, int* height, GLint* internalformat, FrameworkFormat* frameworkFormat = nullptr); bool getBufferInfo(HandleType p_buffer, int* size); @@ -469,7 +453,8 @@ class FrameBuffer { // Create an eglImage and return its handle. Reference: // https://www.khronos.org/registry/egl/extensions/KHR/EGL_KHR_image_base.txt - HandleType createClientImage(HandleType context, EGLenum target, GLuint buffer); + HandleType createClientImage(HandleType context, EGLenum target, + GLuint buffer); // Call the implementation of eglDestroyImageKHR, return if succeeds or // not. Reference: // https://www.khronos.org/registry/egl/extensions/KHR/EGL_KHR_image_base.txt @@ -487,8 +472,7 @@ class FrameBuffer { // GL state. // It can be unsafe / leaky to change the structure of contexts // outside the facilities the FrameBuffer class provides. - void createTrivialContext(HandleType shared, - HandleType* contextOut, + void createTrivialContext(HandleType shared, HandleType* contextOut, HandleType* surfOut); // createAndBindTrivialSharedContext(), but with a m_pbufContext // as shared, and not adding itself to the context map at all. @@ -543,35 +527,29 @@ class FrameBuffer { // nChannels should be 3 (RGB) or 4 (RGBA). // Note: swiftshader_indirect does not work with 3 channels void getScreenshot(unsigned int nChannels, unsigned int* width, - unsigned int* height, std::vector<unsigned char>& pixels, - int displayId, int desiredWidth, int desiredHeight, - int desiredRotation); + unsigned int* height, std::vector<unsigned char>& pixels, + int displayId, int desiredWidth, int desiredHeight, + int desiredRotation); void onLastColorBufferRef(uint32_t handle); ColorBuffer::Helper* getColorBufferHelper() { return m_colorBufferHelper; } ColorBufferPtr findColorBuffer(HandleType p_colorbuffer); - void registerProcessCleanupCallback(void* key, std::function<void()> callback); + void registerProcessCleanupCallback(void* key, + std::function<void()> callback); void unregisterProcessCleanupCallback(void* key); void registerProcessSequenceNumberForPuid(uint64_t puid); uint32_t* getProcessSequenceNumberPtr(uint64_t puid); - int createDisplay(uint32_t *displayId); + int createDisplay(uint32_t* displayId); int destroyDisplay(uint32_t displayId); int setDisplayColorBuffer(uint32_t displayId, uint32_t colorBuffer); int getDisplayColorBuffer(uint32_t displayId, uint32_t* colorBuffer); int getColorBufferDisplay(uint32_t colorBuffer, uint32_t* displayId); - int getDisplayPose(uint32_t displayId, - int32_t* x, - int32_t* y, - uint32_t* w, + int getDisplayPose(uint32_t displayId, int32_t* x, int32_t* y, uint32_t* w, uint32_t* h); - int setDisplayPose(uint32_t displayId, - int32_t x, - int32_t y, - uint32_t w, - uint32_t h, - uint32_t dpi = 0); + int setDisplayPose(uint32_t displayId, int32_t x, int32_t y, uint32_t w, + uint32_t h, uint32_t dpi = 0); void getCombinedDisplaySize(int* w, int* h); struct DisplayInfo { uint32_t cb; @@ -580,8 +558,10 @@ class FrameBuffer { uint32_t width; uint32_t height; uint32_t dpi; - DisplayInfo() : cb(0), pos_x(0), pos_y(0), width(0), height(0), dpi(0) {}; - DisplayInfo(uint32_t cb, int32_t x, int32_t y, uint32_t w, uint32_t h, uint32_t d) + DisplayInfo() + : cb(0), pos_x(0), pos_y(0), width(0), height(0), dpi(0){}; + DisplayInfo(uint32_t cb, int32_t x, int32_t y, uint32_t w, uint32_t h, + uint32_t d) : cb(cb), pos_x(x), pos_y(y), width(w), height(h), dpi(d) {} }; // Inline with MultiDisplay::s_invalidIdMultiDisplay @@ -605,7 +585,8 @@ class FrameBuffer { bool bindFakeWindow_locked(); bool removeSubWindow_locked(); // Returns the set of ColorBuffers destroyed (for further cleanup) - std::vector<HandleType> cleanupProcGLObjects_locked(uint64_t puid, bool forced = false); + std::vector<HandleType> cleanupProcGLObjects_locked(uint64_t puid, + bool forced = false); void markOpened(ColorBufferRef* cbRef); // Returns true if the color buffer was erased. @@ -615,21 +596,17 @@ class FrameBuffer { // Close all expired color buffers for real. // Treat all delayed color buffers as expired if forced=true void performDelayedColorBufferCloseLocked(bool forced = false); - void eraseDelayedCloseColorBufferLocked( - HandleType cb, uint64_t ts); + void eraseDelayedCloseColorBufferLocked(HandleType cb, uint64_t ts); - bool postImpl(HandleType p_colorbuffer, bool needLockAndBind = true, bool repaint = false); + bool postImpl(HandleType p_colorbuffer, bool needLockAndBind = true, + bool repaint = false); void setGuestPostedAFrame() { m_guestPostedAFrame = true; } - HandleType createColorBufferLocked(int p_width, - int p_height, + HandleType createColorBufferLocked(int p_width, int p_height, GLenum p_internalFormat, FrameworkFormat p_frameworkFormat); HandleType createColorBufferWithHandleLocked( - int p_width, - int p_height, - GLenum p_internalFormat, - FrameworkFormat p_frameworkFormat, - HandleType handle); + int p_width, int p_height, GLenum p_internalFormat, + FrameworkFormat p_frameworkFormat, HandleType handle); HandleType createBufferLocked(int p_size); HandleType createBufferWithHandleLocked(int p_size, HandleType handle); @@ -637,8 +614,8 @@ class FrameBuffer { void setDisplayPoseInSkinUI(int totalHeight); void sweepColorBuffersLocked(); -private: - static FrameBuffer *s_theFrameBuffer; + private: + static FrameBuffer* s_theFrameBuffer; static HandleType s_nextHandle; int m_x = 0; int m_y = 0; @@ -680,8 +657,8 @@ private: // // Note: this collection is ordered by |ts| field. struct ColorBufferCloseInfo { - uint64_t ts; // when we got the close request. - HandleType cbHandle; // 0 == already closed, do nothing + uint64_t ts; // when we got the close request. + HandleType cbHandle; // 0 == already closed, do nothing }; using ColorBufferDelayedClose = std::vector<ColorBufferCloseInfo>; ColorBufferDelayedClose m_colorBufferDelayedCloseList; @@ -701,11 +678,11 @@ private: EGLSurface m_prevDrawSurf = EGL_NO_SURFACE; EGLNativeWindowType m_subWin = {}; TextureDraw* m_textureDraw = nullptr; - EGLConfig m_eglConfig = nullptr; + EGLConfig m_eglConfig = nullptr; HandleType m_lastPostedColorBuffer = 0; - float m_zRot = 0; - float m_px = 0; - float m_py = 0; + float m_zRot = 0; + float m_px = 0; + float m_py = 0; // Async readback enum class ReadbackCmd { @@ -724,7 +701,8 @@ private: uint32_t width; uint32_t height; }; - android::base::WorkerProcessingResult sendReadbackWorkerCmd(const Readback& readback); + android::base::WorkerProcessingResult sendReadbackWorkerCmd( + const Readback& readback); bool m_asyncReadbackSupported = true; bool m_guestPostedAFrame = false; diff --git a/stream-servers/tests/DisplayVk_unittest.cpp b/stream-servers/tests/DisplayVk_unittest.cpp index 28ff2b99..fee17470 100644 --- a/stream-servers/tests/DisplayVk_unittest.cpp +++ b/stream-servers/tests/DisplayVk_unittest.cpp @@ -227,10 +227,10 @@ TEST_F(DisplayVkTest, PostWithoutSurfaceShouldntCrash) { textureWidth, textureHeight); std::vector<uint32_t> pixels(textureWidth * textureHeight, 0); ASSERT_TRUE(texture->write(pixels)); - displayVk.importVkImage(0, texture->m_vkImage, RenderTexture::k_vkFormat, - textureWidth, textureHeight); - displayVk.post(0); - displayVk.releaseImport(0); + auto cbvk = displayVk.createDisplayBuffer(texture->m_vkImage, + RenderTexture::k_vkFormat, + textureWidth, textureHeight); + displayVk.post(cbvk); } TEST_F(DisplayVkTest, SimplePost) { @@ -251,12 +251,12 @@ TEST_F(DisplayVkTest, SimplePost) { } } ASSERT_TRUE(texture->write(pixels)); - m_displayVk->importVkImage(0, texture->m_vkImage, texture->k_vkFormat, - texture->m_width, texture->m_height); + auto cbvk = m_displayVk->createDisplayBuffer( + texture->m_vkImage, texture->k_vkFormat, texture->m_width, + texture->m_height); for (uint32_t i = 0; i < 10; i++) { - m_displayVk->post(0); + m_displayVk->post(cbvk); } - m_displayVk->releaseImport(0); } TEST_F(DisplayVkTest, PostTwoColorBuffers) { @@ -274,15 +274,14 @@ TEST_F(DisplayVkTest, PostTwoColorBuffers) { std::vector<uint32_t> greenPixels(textureWidth * textureHeight, green); ASSERT_TRUE(redTexture->write(redPixels)); ASSERT_TRUE(greenTexture->write(greenPixels)); - m_displayVk->importVkImage(0, redTexture->m_vkImage, redTexture->k_vkFormat, - redTexture->m_width, redTexture->m_height); - m_displayVk->importVkImage(1, greenTexture->m_vkImage, - greenTexture->k_vkFormat, greenTexture->m_width, - greenTexture->m_height); + auto redCbvk = m_displayVk->createDisplayBuffer( + redTexture->m_vkImage, redTexture->k_vkFormat, redTexture->m_width, + redTexture->m_height); + auto greenCbvk = m_displayVk->createDisplayBuffer( + greenTexture->m_vkImage, greenTexture->k_vkFormat, + greenTexture->m_width, greenTexture->m_height); for (uint32_t i = 0; i < 10; i++) { - m_displayVk->post(0); - m_displayVk->post(1); + m_displayVk->post(redCbvk); + m_displayVk->post(greenCbvk); } - m_displayVk->releaseImport(0); - m_displayVk->releaseImport(1); }
\ No newline at end of file |