Merge "[HWUI] use ANativeWindow_getLastQueuedBuffer api"

This commit is contained in:
TreeHugger Robot
2020-02-14 00:24:35 +00:00
committed by Android (Google) Code Review
4 changed files with 32 additions and 24 deletions

View File

@@ -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 @@ 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<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);
}

View File

@@ -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);

View File

@@ -317,8 +317,9 @@ void RenderProxy::setRenderAheadDepth(int renderAhead) {
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);
}));
}

View File

@@ -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>& surface, int left, int top, int right,
int bottom, SkBitmap* bitmap);
ANDROID_API static void prepareToDraw(Bitmap& bitmap);