Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 320d3852 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[HWUI] use ANativeWindow_getLastQueuedBuffer api"

parents 429cbb9f 8a82b141
Loading
Loading
Loading
Loading
+25 −22
Original line number Diff line number Diff line
@@ -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);
}

+1 −1
Original line number Diff line number Diff line
@@ -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);

+2 −1
Original line number Diff line number Diff line
@@ -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);
    }));
}

+4 −0
Original line number Diff line number Diff line
@@ -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);