[HWUI] use ANativeWindow_getLastQueuedBuffer api
Bug: 137012798
Test: builds
Change-Id: Ic33a21a73b0579726f47c53cc102fb91b5ead0d6
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index 89a9b99..84c07d7 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 <gui/Surface.h>
-#include <ui/Fence.h>
+#include <sync/sync.h>
+#include <system/window.h>
#include <ui/GraphicBuffer.h>
+
#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 @@
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<GraphicBuffer> sourceBuffer;
- sp<Fence> 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<AHardwareBuffer, decltype(&AHardwareBuffer_release)> 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<SkColorSpace> colorSpace =
- DataSpaceToColorSpace(static_cast<android_dataspace>(surface.getBuffersDataSpace()));
- sk_sp<SkImage> image = SkImage::MakeFromAHardwareBuffer(
- reinterpret_cast<AHardwareBuffer*>(sourceBuffer.get()),
- kPremul_SkAlphaType, colorSpace);
+ sk_sp<SkColorSpace> colorSpace = DataSpaceToColorSpace(
+ static_cast<android_dataspace>(ANativeWindow_getBuffersDataSpace(window)));
+ sk_sp<SkImage> 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 e86a813..e36f1ff 100644
--- a/libs/hwui/Readback.h
+++ b/libs/hwui/Readback.h
@@ -47,7 +47,7 @@
/**
* 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 f9e401a..1e7fc71 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -317,8 +317,9 @@
int RenderProxy::copySurfaceInto(sp<Surface>& surface, int left, int top, int right, int bottom,
SkBitmap* bitmap) {
auto& thread = RenderThread::getInstance();
+ ANativeWindow* window = surface.get();
return static_cast<int>(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 4683e1d..ab0dd2b 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -140,6 +140,10 @@
*/
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>& surface, int left, int top, int right,
int bottom, SkBitmap* bitmap);
ANDROID_API static void prepareToDraw(Bitmap& bitmap);