1500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev/*
2500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev * Copyright (C) 2016 The Android Open Source Project
3500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev *
4500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev * Licensed under the Apache License, Version 2.0 (the "License");
5500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev * you may not use this file except in compliance with the License.
6500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev * You may obtain a copy of the License at
7500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev *
8500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev *      http://www.apache.org/licenses/LICENSE-2.0
9500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev *
10500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev * Unless required by applicable law or agreed to in writing, software
11500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev * distributed under the License is distributed on an "AS IS" BASIS,
12500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev * See the License for the specific language governing permissions and
14500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev * limitations under the License.
15500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev */
16500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
17500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev#include "SkiaVulkanPipeline.h"
18500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
19500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev#include "DeferredLayerUpdater.h"
20cd55852fcd840f7f4c4d7a0a7253a2995c77afa2Greg Daniel#include "renderthread/Frame.h"
21500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev#include "Readback.h"
22500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev#include "renderstate/RenderState.h"
23cf2c05c652190ddc66f873192c17d193478138a1Matt Sarett#include "SkiaPipeline.h"
24cf2c05c652190ddc66f873192c17d193478138a1Matt Sarett#include "SkiaProfileRenderer.h"
258cd3edfa15cc9cdbffa935d19ab894426b08d174Greg Daniel#include "VkLayer.h"
26500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
270e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger#include <SkSurface.h>
28500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev#include <SkTypes.h>
290e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger
300e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger#include <GrContext.h>
310e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger#include <GrTypes.h>
320e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger#include <vk/GrVkTypes.h>
33500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
34500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev#include <cutils/properties.h>
35500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev#include <strings.h>
36500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
37500a0c30d4dcd012218c3e44a62926a1c34a259fStan Ilievusing namespace android::uirenderer::renderthread;
38500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
39500a0c30d4dcd012218c3e44a62926a1c34a259fStan Ilievnamespace android {
40500a0c30d4dcd012218c3e44a62926a1c34a259fStan Ilievnamespace uirenderer {
41500a0c30d4dcd012218c3e44a62926a1c34a259fStan Ilievnamespace skiapipeline {
42500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
430e3cba31460e0698def0310003b7d291f1174afaDerek SollenbergerSkiaVulkanPipeline::SkiaVulkanPipeline(renderthread::RenderThread& thread)
440e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger        : SkiaPipeline(thread)
450e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger        , mVkManager(thread.vulkanManager()) {}
460e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger
47500a0c30d4dcd012218c3e44a62926a1c34a259fStan IlievMakeCurrentResult SkiaVulkanPipeline::makeCurrent() {
480e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger    return MakeCurrentResult::AlreadyCurrent;
49500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev}
50500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
51500a0c30d4dcd012218c3e44a62926a1c34a259fStan IlievFrame SkiaVulkanPipeline::getFrame() {
520e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger    LOG_ALWAYS_FATAL_IF(mVkSurface == nullptr,
530e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger                "drawRenderNode called on a context with no surface!");
540e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger
550e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger    SkSurface* backBuffer = mVkManager.getBackbufferSurface(mVkSurface);
560e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger    if (backBuffer == nullptr) {
57500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev        SkDebugf("failed to get backbuffer");
58500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev        return Frame(-1, -1, 0);
59500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev    }
60500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
61cd55852fcd840f7f4c4d7a0a7253a2995c77afa2Greg Daniel    Frame frame(backBuffer->width(), backBuffer->height(), mVkManager.getAge(mVkSurface));
62500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev    return frame;
63500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev}
64500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
65500a0c30d4dcd012218c3e44a62926a1c34a259fStan Ilievbool SkiaVulkanPipeline::draw(const Frame& frame, const SkRect& screenDirty,
66500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev        const SkRect& dirty,
67500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev        const FrameBuilder::LightGeometry& lightGeometry,
68500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev        LayerUpdateQueue* layerUpdateQueue,
69500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev        const Rect& contentDrawBounds, bool opaque,
70500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev        const BakedOpRenderer::LightInfo& lightInfo,
71500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev        const std::vector<sp<RenderNode>>& renderNodes,
72500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev        FrameInfoVisualizer* profiler) {
73500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
740e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger    sk_sp<SkSurface> backBuffer = mVkSurface->getBackBufferSurface();
750e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger    if (backBuffer.get() == nullptr) {
76500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev        return false;
77500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev    }
780e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger    SkiaPipeline::updateLighting(lightGeometry, lightInfo);
790e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, backBuffer);
80500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev    layerUpdateQueue->clear();
81cf2c05c652190ddc66f873192c17d193478138a1Matt Sarett
82cf2c05c652190ddc66f873192c17d193478138a1Matt Sarett    // Draw visual debugging features
83cf2c05c652190ddc66f873192c17d193478138a1Matt Sarett    if (CC_UNLIKELY(Properties::showDirtyRegions
844c9bbf4eef4c8eef44c16d908cb84c343d4a1a81Matt Sarett            || ProfileType::None != Properties::getProfileType())) {
850e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger        SkCanvas* profileCanvas = backBuffer->getCanvas();
86cf2c05c652190ddc66f873192c17d193478138a1Matt Sarett        SkiaProfileRenderer profileRenderer(profileCanvas);
87cf2c05c652190ddc66f873192c17d193478138a1Matt Sarett        profiler->draw(profileRenderer);
88cf2c05c652190ddc66f873192c17d193478138a1Matt Sarett        profileCanvas->flush();
89cf2c05c652190ddc66f873192c17d193478138a1Matt Sarett    }
90cf2c05c652190ddc66f873192c17d193478138a1Matt Sarett
914bda6bfaa6b8cb775f18f2453720d05f4cb29152Matt Sarett    // Log memory statistics
924bda6bfaa6b8cb775f18f2453720d05f4cb29152Matt Sarett    if (CC_UNLIKELY(Properties::debugLevel != kDebugDisabled)) {
934bda6bfaa6b8cb775f18f2453720d05f4cb29152Matt Sarett        dumpResourceCacheUsage();
944bda6bfaa6b8cb775f18f2453720d05f4cb29152Matt Sarett    }
954bda6bfaa6b8cb775f18f2453720d05f4cb29152Matt Sarett
96500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev    return true;
97500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev}
98500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
99500a0c30d4dcd012218c3e44a62926a1c34a259fStan Ilievbool SkiaVulkanPipeline::swapBuffers(const Frame& frame, bool drew,
100500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev        const SkRect& screenDirty, FrameInfo* currentFrameInfo, bool* requireSwap) {
101500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
102500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev    *requireSwap = drew;
103500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
104500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev    // Even if we decided to cancel the frame, from the perspective of jank
105500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev    // metrics the frame was swapped at this point
106500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev    currentFrameInfo->markSwapBuffers();
107500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
108500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev    if (*requireSwap) {
1090e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger        mVkManager.swapBuffers(mVkSurface);
110500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev    }
111500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
112500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev    return *requireSwap;
113500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev}
114500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
115500a0c30d4dcd012218c3e44a62926a1c34a259fStan Ilievbool SkiaVulkanPipeline::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
116500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev    // TODO: implement copyLayerInto for vulkan.
117500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev    return false;
118500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev}
119500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
1203e9999bd866fac71c72e6b484a9836c87c328a08sergeyvstatic Layer* createLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight,
1213e9999bd866fac71c72e6b484a9836c87c328a08sergeyv        SkColorFilter* colorFilter, int alpha, SkBlendMode mode, bool blend) {
1223e9999bd866fac71c72e6b484a9836c87c328a08sergeyv    return new VkLayer(renderState, layerWidth, layerHeight, colorFilter, alpha, mode, blend);
1233e9999bd866fac71c72e6b484a9836c87c328a08sergeyv}
1243e9999bd866fac71c72e6b484a9836c87c328a08sergeyv
125500a0c30d4dcd012218c3e44a62926a1c34a259fStan IlievDeferredLayerUpdater* SkiaVulkanPipeline::createTextureLayer() {
1260e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger    mVkManager.initialize();
1278cd3edfa15cc9cdbffa935d19ab894426b08d174Greg Daniel
1283e9999bd866fac71c72e6b484a9836c87c328a08sergeyv    return new DeferredLayerUpdater(mRenderThread.renderState(), createLayer, Layer::Api::Vulkan);
129500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev}
130500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
131500a0c30d4dcd012218c3e44a62926a1c34a259fStan Ilievvoid SkiaVulkanPipeline::onStop() {
132500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev}
133500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
134500a0c30d4dcd012218c3e44a62926a1c34a259fStan Ilievbool SkiaVulkanPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior) {
1350e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger    if (mVkSurface) {
1360e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger        mVkManager.destroySurface(mVkSurface);
1370e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger        mVkSurface = nullptr;
138500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev    }
139500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
140500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev    if (surface) {
1410e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger        mVkSurface = mVkManager.createSurface(surface);
142500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev    }
143500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
1440e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger    return mVkSurface != nullptr;
145500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev}
146500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
147500a0c30d4dcd012218c3e44a62926a1c34a259fStan Ilievbool SkiaVulkanPipeline::isSurfaceReady() {
1480e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger    return CC_UNLIKELY(mVkSurface != nullptr);
149500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev}
150500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
151500a0c30d4dcd012218c3e44a62926a1c34a259fStan Ilievbool SkiaVulkanPipeline::isContextReady() {
1520e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger    return CC_LIKELY(mVkManager.hasVkContext());
153500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev}
154500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
155500a0c30d4dcd012218c3e44a62926a1c34a259fStan Ilievvoid SkiaVulkanPipeline::invokeFunctor(const RenderThread& thread, Functor* functor) {
156500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev    // TODO: we currently don't support OpenGL WebView's
157500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev    DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext;
158500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev    (*functor)(mode, nullptr);
159500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev}
160500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev
161500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev} /* namespace skiapipeline */
162500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev} /* namespace uirenderer */
163500a0c30d4dcd012218c3e44a62926a1c34a259fStan Iliev} /* namespace android */
164