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

Commit af9dc4dc authored by Derek Sollenberger's avatar Derek Sollenberger Committed by Android (Google) Code Review
Browse files

Merge "Handle vulkan windowing directly in SkiaVulkanPipeline"

parents b53e048b 0e3cba31
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ hwui_src_files := \
    renderthread/OpenGLPipeline.cpp \
    renderthread/DrawFrameTask.cpp \
    renderthread/EglManager.cpp \
    renderthread/VulkanManager.cpp \
    renderthread/RenderProxy.cpp \
    renderthread/RenderTask.cpp \
    renderthread/RenderThread.cpp \
+1 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ LOCAL_SHARED_LIBRARIES += \
    libutils \
    libEGL \
    libGLESv2 \
    libvulkan \
    libskia \
    libui \
    libgui \
+30 −32
Original line number Diff line number Diff line
@@ -23,37 +23,43 @@
#include "SkiaPipeline.h"
#include "SkiaProfileRenderer.h"

#include <SkSurface.h>
#include <SkTypes.h>
#include <WindowContextFactory_android.h>
#include <VulkanWindowContext.h>

#include <GrContext.h>
#include <GrTypes.h>
#include <vk/GrVkTypes.h>

#include <android/native_window.h>
#include <cutils/properties.h>
#include <strings.h>

using namespace android::uirenderer::renderthread;
using namespace sk_app;

namespace android {
namespace uirenderer {
namespace skiapipeline {

SkiaVulkanPipeline::SkiaVulkanPipeline(renderthread::RenderThread& thread)
        : SkiaPipeline(thread)
        , mVkManager(thread.vulkanManager()) {}

MakeCurrentResult SkiaVulkanPipeline::makeCurrent() {
    return (mWindowContext != nullptr) ?
        MakeCurrentResult::AlreadyCurrent : MakeCurrentResult::Failed;
    return MakeCurrentResult::AlreadyCurrent;
}

Frame SkiaVulkanPipeline::getFrame() {
    LOG_ALWAYS_FATAL_IF(mWindowContext == nullptr, "Tried to draw into null vulkan context!");
    mBackbuffer = mWindowContext->getBackbufferSurface();
    if (mBackbuffer.get() == nullptr) {
        // try recreating the context?
    LOG_ALWAYS_FATAL_IF(mVkSurface == nullptr,
                "drawRenderNode called on a context with no surface!");

    SkSurface* backBuffer = mVkManager.getBackbufferSurface(mVkSurface);
    if (backBuffer == nullptr) {
        SkDebugf("failed to get backbuffer");
        return Frame(-1, -1, 0);
    }

    // TODO: support buffer age if Vulkan API can do it
    Frame frame(mBackbuffer->width(), mBackbuffer->height(), 0);
    Frame frame(backBuffer->width(), backBuffer->height(), 0);
    return frame;
}

@@ -66,16 +72,18 @@ bool SkiaVulkanPipeline::draw(const Frame& frame, const SkRect& screenDirty,
        const std::vector<sp<RenderNode>>& renderNodes,
        FrameInfoVisualizer* profiler) {

    if (mBackbuffer.get() == nullptr) {
    sk_sp<SkSurface> backBuffer = mVkSurface->getBackBufferSurface();
    if (backBuffer.get() == nullptr) {
        return false;
    }
    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, mBackbuffer);
    SkiaPipeline::updateLighting(lightGeometry, lightInfo);
    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, backBuffer);
    layerUpdateQueue->clear();

    // Draw visual debugging features
    if (CC_UNLIKELY(Properties::showDirtyRegions
            || ProfileType::None != Properties::getProfileType())) {
        SkCanvas* profileCanvas = mBackbuffer->getCanvas();
        SkCanvas* profileCanvas = backBuffer->getCanvas();
        SkiaProfileRenderer profileRenderer(profileCanvas);
        profiler->draw(profileRenderer);
        profileCanvas->flush();
@@ -99,11 +107,9 @@ bool SkiaVulkanPipeline::swapBuffers(const Frame& frame, bool drew,
    currentFrameInfo->markSwapBuffers();

    if (*requireSwap) {
        mWindowContext->swapBuffers();
        mVkManager.swapBuffers(mVkSurface);
    }

    mBackbuffer.reset();

    return *requireSwap;
}

@@ -113,6 +119,7 @@ bool SkiaVulkanPipeline::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bi
}

DeferredLayerUpdater* SkiaVulkanPipeline::createTextureLayer() {
    mVkManager.initialize();
    Layer* layer = new Layer(mRenderThread.renderState(), 0, 0);
    return new DeferredLayerUpdater(layer);
}
@@ -121,33 +128,24 @@ void SkiaVulkanPipeline::onStop() {
}

bool SkiaVulkanPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior) {

    if (mWindowContext) {
        delete mWindowContext;
        mWindowContext = nullptr;
    if (mVkSurface) {
        mVkManager.destroySurface(mVkSurface);
        mVkSurface = nullptr;
    }

    if (surface) {
        DisplayParams displayParams;
        mWindowContext = window_context_factory::NewVulkanForAndroid(surface, displayParams);
        if (mWindowContext) {
            DeviceInfo::initialize(mWindowContext->getGrContext()->caps()->maxRenderTargetSize());
        }
        mVkSurface = mVkManager.createSurface(surface);
    }


    // this doesn't work for if there is more than one CanvasContext available at one time!
    mRenderThread.setGrContext(mWindowContext ? mWindowContext->getGrContext() : nullptr);

    return mWindowContext != nullptr;
    return mVkSurface != nullptr;
}

bool SkiaVulkanPipeline::isSurfaceReady() {
    return CC_LIKELY(mWindowContext != nullptr) && mWindowContext->isValid();
    return CC_UNLIKELY(mVkSurface != nullptr);
}

bool SkiaVulkanPipeline::isContextReady() {
    return CC_LIKELY(mWindowContext != nullptr);
    return CC_LIKELY(mVkManager.hasVkContext());
}

void SkiaVulkanPipeline::invokeFunctor(const RenderThread& thread, Functor* functor) {
+4 −8
Original line number Diff line number Diff line
@@ -17,11 +17,7 @@
#pragma once

#include "SkiaPipeline.h"
#include <SkSurface.h>

namespace sk_app {
class WindowContext;
}
#include "renderthread/VulkanManager.h"

namespace android {
namespace uirenderer {
@@ -29,7 +25,7 @@ namespace skiapipeline {

class SkiaVulkanPipeline : public SkiaPipeline {
public:
    SkiaVulkanPipeline(renderthread::RenderThread& thread) : SkiaPipeline(thread) {}
    SkiaVulkanPipeline(renderthread::RenderThread& thread);
    virtual ~SkiaVulkanPipeline() {}

    renderthread::MakeCurrentResult makeCurrent() override;
@@ -53,8 +49,8 @@ public:
    static void invokeFunctor(const renderthread::RenderThread& thread, Functor* functor);

private:
    sk_app::WindowContext* mWindowContext = nullptr;
    sk_sp<SkSurface> mBackbuffer;
    renderthread::VulkanManager& mVkManager;
    renderthread::VulkanSurface* mVkSurface = nullptr;
};

} /* namespace skiapipeline */
+4 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include "CanvasContext.h"
#include "EglManager.h"
#include "RenderProxy.h"
#include "VulkanManager.h"

#include <gui/DisplayEventReceiver.h>
#include <gui/ISurfaceComposer.h>
@@ -157,7 +158,8 @@ RenderThread::RenderThread() : Thread(true)
        , mFrameCallbackTaskPending(false)
        , mFrameCallbackTask(nullptr)
        , mRenderState(nullptr)
        , mEglManager(nullptr) {
        , mEglManager(nullptr)
        , mVkManager(nullptr) {
    Properties::load();
    mFrameCallbackTask = new DispatchFrameCallbacks(this);
    mLooper = new Looper(false);
@@ -191,6 +193,7 @@ void RenderThread::initThreadLocals() {
    mEglManager = new EglManager(*this);
    mRenderState = new RenderState(*this);
    mJankTracker = new JankTracker(mDisplayInfo);
    mVkManager = new VulkanManager(*this);
}

int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) {
Loading