• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "VkFunctorDrawable.h"
18 
19 #include <SkAndroidFrameworkUtils.h>
20 #include <SkImage.h>
21 #include <SkM44.h>
22 #include <include/gpu/ganesh/vk/GrBackendDrawableInfo.h>
23 #include <gui/TraceUtils.h>
24 #include <private/hwui/DrawVkInfo.h>
25 #include <utils/Color.h>
26 #include <utils/Trace.h>
27 #include <vk/GrVkTypes.h>
28 
29 #include <thread>
30 
31 #include "effects/GainmapRenderer.h"
32 #include "renderthread/CanvasContext.h"
33 #include "renderthread/RenderThread.h"
34 #include "renderthread/VulkanManager.h"
35 #include "thread/ThreadBase.h"
36 #include "utils/TimeUtils.h"
37 
38 namespace android {
39 namespace uirenderer {
40 namespace skiapipeline {
41 
VkFunctorDrawHandler(sp<WebViewFunctor::Handle> functor_handle,const SkMatrix & matrix,const SkIRect & clip,const SkImageInfo & image_info)42 VkFunctorDrawHandler::VkFunctorDrawHandler(sp<WebViewFunctor::Handle> functor_handle,
43                                            const SkMatrix& matrix, const SkIRect& clip,
44                                            const SkImageInfo& image_info)
45         : INHERITED()
46         , mFunctorHandle(functor_handle)
47         , mMatrix(matrix)
48         , mClip(clip)
49         , mImageInfo(image_info) {}
50 
~VkFunctorDrawHandler()51 VkFunctorDrawHandler::~VkFunctorDrawHandler() {
52     if (mDrawn) {
53         mFunctorHandle->postDrawVk();
54     }
55 }
56 
draw(const GrBackendDrawableInfo & info)57 void VkFunctorDrawHandler::draw(const GrBackendDrawableInfo& info) {
58     ATRACE_CALL();
59     if (!renderthread::RenderThread::isCurrent())
60         LOG_ALWAYS_FATAL("VkFunctorDrawHandler::draw not called on render thread");
61 
62     GrVkDrawableInfo vulkan_info;
63     if (!info.getVkDrawableInfo(&vulkan_info)) {
64         return;
65     }
66     renderthread::VulkanManager& vk_manager =
67             renderthread::RenderThread::getInstance().vulkanManager();
68     mFunctorHandle->initVk(vk_manager.getVkFunctorInitParams());
69 
70     SkM44 mat4(mMatrix);
71     VkFunctorDrawParams params{
72             .width = mImageInfo.width(),
73             .height = mImageInfo.height(),
74             .color_space_ptr = mImageInfo.colorSpace(),
75             .clip_left = mClip.fLeft,
76             .clip_top = mClip.fTop,
77             .clip_right = mClip.fRight,
78             .clip_bottom = mClip.fBottom,
79             .is_layer = !vulkan_info.fFromSwapchainOrAndroidWindow,
80             .currentHdrSdrRatio = getTargetHdrSdrRatio(mImageInfo.colorSpace()),
81             .shouldDither = renderthread::CanvasContext::shouldDither(),
82     };
83     mat4.getColMajor(&params.transform[0]);
84     params.secondary_command_buffer = vulkan_info.fSecondaryCommandBuffer;
85     params.color_attachment_index = vulkan_info.fColorAttachmentIndex;
86     params.compatible_render_pass = vulkan_info.fCompatibleRenderPass;
87     params.format = vulkan_info.fFormat;
88 
89     mFunctorHandle->drawVk(params);
90     mDrawn = true;
91 
92     vulkan_info.fDrawBounds->offset.x = mClip.fLeft;
93     vulkan_info.fDrawBounds->offset.y = mClip.fTop;
94     vulkan_info.fDrawBounds->extent.width = mClip.fRight - mClip.fLeft;
95     vulkan_info.fDrawBounds->extent.height = mClip.fBottom - mClip.fTop;
96 }
97 
~VkFunctorDrawable()98 VkFunctorDrawable::~VkFunctorDrawable() {}
99 
onDraw(SkCanvas * canvas)100 void VkFunctorDrawable::onDraw(SkCanvas* canvas) {
101     // "canvas" is either SkNWayCanvas created by SkiaPipeline::tryCapture (SKP capture use case) or
102     // AlphaFilterCanvas (used by RenderNodeDrawable to apply alpha in certain cases).
103     // "VkFunctorDrawable::onDraw" is not invoked for the most common case, when drawing in a GPU
104     // canvas.
105 
106     if (canvas->recordingContext() == nullptr) {
107         // We're dumping a picture, render a light-blue rectangle instead
108         SkPaint paint;
109         paint.setColor(0xFF81D4FA);
110         canvas->drawRect(mBounds, paint);
111     } else {
112         // Handle the case when "canvas" is AlphaFilterCanvas. Find the wrapped GPU canvas.
113         SkCanvas* gpuCanvas = SkAndroidFrameworkUtils::getBaseWrappedCanvas(canvas);
114         // Enforce "canvas" must be an AlphaFilterCanvas. For GPU canvas, the call should come from
115         // onSnapGpuDrawHandler.
116         LOG_ALWAYS_FATAL_IF(gpuCanvas == canvas,
117                             "VkFunctorDrawable::onDraw() should not be called with a GPU canvas!");
118 
119         // This will invoke onSnapGpuDrawHandler and regular draw flow.
120         gpuCanvas->drawDrawable(this);
121     }
122 }
123 
onSnapGpuDrawHandler(GrBackendApi backendApi,const SkMatrix & matrix,const SkIRect & clip,const SkImageInfo & image_info)124 std::unique_ptr<FunctorDrawable::GpuDrawHandler> VkFunctorDrawable::onSnapGpuDrawHandler(
125         GrBackendApi backendApi, const SkMatrix& matrix, const SkIRect& clip,
126         const SkImageInfo& image_info) {
127     if (backendApi != GrBackendApi::kVulkan) {
128         return nullptr;
129     }
130     std::unique_ptr<VkFunctorDrawHandler> draw;
131     return std::make_unique<VkFunctorDrawHandler>(mWebViewHandle, matrix, clip, image_info);
132 }
133 
134 }  // namespace skiapipeline
135 }  // namespace uirenderer
136 }  // namespace android
137