From 8a82b141d1fda246a9353f04a1af09144334e451 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Tue, 17 Dec 2019 09:41:48 -0800 Subject: [PATCH] [HWUI] use ANativeWindow_getLastQueuedBuffer api Bug: 137012798 Test: builds Change-Id: Ic33a21a73b0579726f47c53cc102fb91b5ead0d6 --- libs/hwui/Readback.cpp | 47 ++++++++++++++------------ libs/hwui/Readback.h | 2 +- libs/hwui/renderthread/RenderProxy.cpp | 3 +- libs/hwui/renderthread/RenderProxy.h | 4 +++ 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp index 89a9b997af974..84c07d7d9dffc 100644 --- a/libs/hwui/Readback.cpp +++ b/libs/hwui/Readback.cpp @@ -16,16 +16,16 @@ #include "Readback.h" -#include "pipeline/skia/LayerDrawable.h" -#include "renderthread/EglManager.h" -#include "renderthread/VulkanManager.h" - -#include -#include +#include +#include #include + #include "DeferredLayerUpdater.h" #include "Properties.h" #include "hwui/Bitmap.h" +#include "pipeline/skia/LayerDrawable.h" +#include "renderthread/EglManager.h" +#include "renderthread/VulkanManager.h" #include "utils/Color.h" #include "utils/MathUtils.h" #include "utils/TraceUtils.h" @@ -35,40 +35,43 @@ using namespace android::uirenderer::renderthread; namespace android { namespace uirenderer { -CopyResult Readback::copySurfaceInto(Surface& surface, const Rect& srcRect, SkBitmap* bitmap) { +CopyResult Readback::copySurfaceInto(ANativeWindow* window, const Rect& srcRect, SkBitmap* bitmap) { ATRACE_CALL(); // Setup the source - sp sourceBuffer; - sp sourceFence; + AHardwareBuffer* rawSourceBuffer; + int rawSourceFence; Matrix4 texTransform; - status_t err = surface.getLastQueuedBuffer(&sourceBuffer, &sourceFence, texTransform.data); + status_t err = ANativeWindow_getLastQueuedBuffer(window, &rawSourceBuffer, &rawSourceFence, + texTransform.data); + base::unique_fd sourceFence(rawSourceFence); texTransform.invalidateType(); if (err != NO_ERROR) { ALOGW("Failed to get last queued buffer, error = %d", err); return CopyResult::UnknownError; } - if (!sourceBuffer.get()) { + if (rawSourceBuffer == nullptr) { ALOGW("Surface doesn't have any previously queued frames, nothing to readback from"); return CopyResult::SourceEmpty; } - if (sourceBuffer->getUsage() & GRALLOC_USAGE_PROTECTED) { + + std::unique_ptr sourceBuffer( + rawSourceBuffer, AHardwareBuffer_release); + AHardwareBuffer_Desc description; + AHardwareBuffer_describe(sourceBuffer.get(), &description); + if (description.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT) { ALOGW("Surface is protected, unable to copy from it"); return CopyResult::SourceInvalid; } - err = sourceFence->wait(500 /* ms */); - if (err != NO_ERROR) { + + if (sourceFence != -1 && sync_wait(sourceFence.get(), 500 /* ms */) != NO_ERROR) { ALOGE("Timeout (500ms) exceeded waiting for buffer fence, abandoning readback attempt"); return CopyResult::Timeout; } - if (!sourceBuffer.get()) { - return CopyResult::UnknownError; - } - sk_sp colorSpace = - DataSpaceToColorSpace(static_cast(surface.getBuffersDataSpace())); - sk_sp image = SkImage::MakeFromAHardwareBuffer( - reinterpret_cast(sourceBuffer.get()), - kPremul_SkAlphaType, colorSpace); + sk_sp colorSpace = DataSpaceToColorSpace( + static_cast(ANativeWindow_getBuffersDataSpace(window))); + sk_sp image = + SkImage::MakeFromAHardwareBuffer(sourceBuffer.get(), kPremul_SkAlphaType, colorSpace); return copyImageInto(image, texTransform, srcRect, bitmap); } diff --git a/libs/hwui/Readback.h b/libs/hwui/Readback.h index e86a8136cfa38..e36f1ff6a072f 100644 --- a/libs/hwui/Readback.h +++ b/libs/hwui/Readback.h @@ -47,7 +47,7 @@ public: /** * Copies the surface's most recently queued buffer into the provided bitmap. */ - CopyResult copySurfaceInto(Surface& surface, const Rect& srcRect, SkBitmap* bitmap); + CopyResult copySurfaceInto(ANativeWindow* window, const Rect& srcRect, SkBitmap* bitmap); CopyResult copyHWBitmapInto(Bitmap* hwBitmap, SkBitmap* bitmap); diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index f9e401a2e93b2..1e7fc71a7f047 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -317,8 +317,9 @@ void RenderProxy::setRenderAheadDepth(int renderAhead) { int RenderProxy::copySurfaceInto(sp& surface, int left, int top, int right, int bottom, SkBitmap* bitmap) { auto& thread = RenderThread::getInstance(); + ANativeWindow* window = surface.get(); return static_cast(thread.queue().runSync([&]() -> auto { - return thread.readback().copySurfaceInto(*surface, Rect(left, top, right, bottom), bitmap); + return thread.readback().copySurfaceInto(window, Rect(left, top, right, bottom), bitmap); })); } diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index 4683e1d69019c..ab0dd2bcc8f59 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -140,6 +140,10 @@ public: */ ANDROID_API void setRenderAheadDepth(int renderAhead); + // TODO: This api will need to take in an ANativeWindow instead, but the + // caller, ThreadedRenderer, doesn't have access to libandroid due to a + // circular dependency, so it can't use the JNI ANativeWindow methods. Once + // that is resolved then replace the surface type here. ANDROID_API static int copySurfaceInto(sp& surface, int left, int top, int right, int bottom, SkBitmap* bitmap); ANDROID_API static void prepareToDraw(Bitmap& bitmap);