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 #include <private/hwui/DrawVkInfo.h> 19 20 #include <GrBackendDrawableInfo.h> 21 #include <SkAndroidFrameworkUtils.h> 22 #include <SkImage.h> 23 #include <utils/Color.h> 24 #include <utils/Trace.h> 25 #include <utils/TraceUtils.h> 26 #include <vk/GrVkTypes.h> 27 #include <thread> 28 #include "renderthread/RenderThread.h" 29 #include "renderthread/VulkanManager.h" 30 #include "thread/ThreadBase.h" 31 #include "utils/TimeUtils.h" 32 33 namespace android { 34 namespace uirenderer { 35 namespace skiapipeline { 36 37 VkFunctorDrawHandler::VkFunctorDrawHandler(sp<WebViewFunctor::Handle> functor_handle, 38 const SkMatrix& matrix, const SkIRect& clip, 39 const SkImageInfo& image_info) 40 : INHERITED() 41 , mFunctorHandle(functor_handle) 42 , mMatrix(matrix) 43 , mClip(clip) 44 , mImageInfo(image_info) {} 45 46 VkFunctorDrawHandler::~VkFunctorDrawHandler() { 47 if (mDrawn) { 48 mFunctorHandle->postDrawVk(); 49 } 50 } 51 52 void VkFunctorDrawHandler::draw(const GrBackendDrawableInfo& info) { 53 ATRACE_CALL(); 54 if (!renderthread::RenderThread::isCurrent()) 55 LOG_ALWAYS_FATAL("VkFunctorDrawHandler::draw not called on render thread"); 56 57 GrVkDrawableInfo vulkan_info; 58 if (!info.getVkDrawableInfo(&vulkan_info)) { 59 return; 60 } 61 renderthread::VulkanManager& vk_manager = 62 renderthread::RenderThread::getInstance().vulkanManager(); 63 mFunctorHandle->initVk(vk_manager.getVkFunctorInitParams()); 64 65 SkMatrix44 mat4(mMatrix); 66 VkFunctorDrawParams params{ 67 .width = mImageInfo.width(), 68 .height = mImageInfo.height(), 69 .color_space_ptr = mImageInfo.colorSpace(), 70 .clip_left = mClip.fLeft, 71 .clip_top = mClip.fTop, 72 .clip_right = mClip.fRight, 73 .clip_bottom = mClip.fBottom, 74 }; 75 mat4.asColMajorf(¶ms.transform[0]); 76 params.secondary_command_buffer = vulkan_info.fSecondaryCommandBuffer; 77 params.color_attachment_index = vulkan_info.fColorAttachmentIndex; 78 params.compatible_render_pass = vulkan_info.fCompatibleRenderPass; 79 params.format = vulkan_info.fFormat; 80 81 mFunctorHandle->drawVk(params); 82 mDrawn = true; 83 84 vulkan_info.fDrawBounds->offset.x = mClip.fLeft; 85 vulkan_info.fDrawBounds->offset.y = mClip.fTop; 86 vulkan_info.fDrawBounds->extent.width = mClip.fRight - mClip.fLeft; 87 vulkan_info.fDrawBounds->extent.height = mClip.fBottom - mClip.fTop; 88 } 89 90 VkFunctorDrawable::~VkFunctorDrawable() {} 91 92 void VkFunctorDrawable::onDraw(SkCanvas* canvas) { 93 // "canvas" is either SkNWayCanvas created by SkiaPipeline::tryCapture (SKP capture use case) or 94 // AlphaFilterCanvas (used by RenderNodeDrawable to apply alpha in certain cases). 95 // "VkFunctorDrawable::onDraw" is not invoked for the most common case, when drawing in a GPU 96 // canvas. 97 98 if (canvas->getGrContext() == nullptr) { 99 // We're dumping a picture, render a light-blue rectangle instead 100 SkPaint paint; 101 paint.setColor(0xFF81D4FA); 102 canvas->drawRect(mBounds, paint); 103 } else { 104 // Handle the case when "canvas" is AlphaFilterCanvas. Find the wrapped GPU canvas. 105 SkCanvas* gpuCanvas = SkAndroidFrameworkUtils::getBaseWrappedCanvas(canvas); 106 // Enforce "canvas" must be an AlphaFilterCanvas. For GPU canvas, the call should come from 107 // onSnapGpuDrawHandler. 108 LOG_ALWAYS_FATAL_IF(gpuCanvas == canvas, 109 "VkFunctorDrawable::onDraw() should not be called with a GPU canvas!"); 110 111 // This will invoke onSnapGpuDrawHandler and regular draw flow. 112 gpuCanvas->drawDrawable(this); 113 } 114 } 115 116 std::unique_ptr<FunctorDrawable::GpuDrawHandler> VkFunctorDrawable::onSnapGpuDrawHandler( 117 GrBackendApi backendApi, const SkMatrix& matrix, const SkIRect& clip, 118 const SkImageInfo& image_info) { 119 if (backendApi != GrBackendApi::kVulkan) { 120 return nullptr; 121 } 122 std::unique_ptr<VkFunctorDrawHandler> draw; 123 if (mAnyFunctor.index() == 0) { 124 return std::make_unique<VkFunctorDrawHandler>(std::get<0>(mAnyFunctor).handle, matrix, clip, 125 image_info); 126 } else { 127 LOG_ALWAYS_FATAL("Not implemented"); 128 } 129 } 130 131 } // namespace skiapipeline 132 } // namespace uirenderer 133 } // namespace android 134