Merge "[HWUI] use ANativeWindow_getLastQueuedBuffer api"
This commit is contained in:
committed by
Android (Google) Code Review
commit
320d3852f6
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user