ce9762b57f
Test: It makes Bug: 183120308 Change-Id: I331262dd2da59817031f0c708f4c102041dcb5e0
130 lines
4.7 KiB
C++
130 lines
4.7 KiB
C++
/*
|
|
* Copyright (C) 2018 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "VkFunctorDrawable.h"
|
|
#include <private/hwui/DrawVkInfo.h>
|
|
|
|
#include <GrBackendDrawableInfo.h>
|
|
#include <SkAndroidFrameworkUtils.h>
|
|
#include <SkImage.h>
|
|
#include <SkM44.h>
|
|
#include <gui/TraceUtils.h>
|
|
#include <utils/Color.h>
|
|
#include <utils/Trace.h>
|
|
#include <vk/GrVkTypes.h>
|
|
#include <thread>
|
|
#include "renderthread/RenderThread.h"
|
|
#include "renderthread/VulkanManager.h"
|
|
#include "thread/ThreadBase.h"
|
|
#include "utils/TimeUtils.h"
|
|
|
|
namespace android {
|
|
namespace uirenderer {
|
|
namespace skiapipeline {
|
|
|
|
VkFunctorDrawHandler::VkFunctorDrawHandler(sp<WebViewFunctor::Handle> functor_handle,
|
|
const SkMatrix& matrix, const SkIRect& clip,
|
|
const SkImageInfo& image_info)
|
|
: INHERITED()
|
|
, mFunctorHandle(functor_handle)
|
|
, mMatrix(matrix)
|
|
, mClip(clip)
|
|
, mImageInfo(image_info) {}
|
|
|
|
VkFunctorDrawHandler::~VkFunctorDrawHandler() {
|
|
if (mDrawn) {
|
|
mFunctorHandle->postDrawVk();
|
|
}
|
|
}
|
|
|
|
void VkFunctorDrawHandler::draw(const GrBackendDrawableInfo& info) {
|
|
ATRACE_CALL();
|
|
if (!renderthread::RenderThread::isCurrent())
|
|
LOG_ALWAYS_FATAL("VkFunctorDrawHandler::draw not called on render thread");
|
|
|
|
GrVkDrawableInfo vulkan_info;
|
|
if (!info.getVkDrawableInfo(&vulkan_info)) {
|
|
return;
|
|
}
|
|
renderthread::VulkanManager& vk_manager =
|
|
renderthread::RenderThread::getInstance().vulkanManager();
|
|
mFunctorHandle->initVk(vk_manager.getVkFunctorInitParams());
|
|
|
|
SkM44 mat4(mMatrix);
|
|
VkFunctorDrawParams params{
|
|
.width = mImageInfo.width(),
|
|
.height = mImageInfo.height(),
|
|
.color_space_ptr = mImageInfo.colorSpace(),
|
|
.clip_left = mClip.fLeft,
|
|
.clip_top = mClip.fTop,
|
|
.clip_right = mClip.fRight,
|
|
.clip_bottom = mClip.fBottom,
|
|
};
|
|
mat4.getColMajor(¶ms.transform[0]);
|
|
params.secondary_command_buffer = vulkan_info.fSecondaryCommandBuffer;
|
|
params.color_attachment_index = vulkan_info.fColorAttachmentIndex;
|
|
params.compatible_render_pass = vulkan_info.fCompatibleRenderPass;
|
|
params.format = vulkan_info.fFormat;
|
|
|
|
mFunctorHandle->drawVk(params);
|
|
mDrawn = true;
|
|
|
|
vulkan_info.fDrawBounds->offset.x = mClip.fLeft;
|
|
vulkan_info.fDrawBounds->offset.y = mClip.fTop;
|
|
vulkan_info.fDrawBounds->extent.width = mClip.fRight - mClip.fLeft;
|
|
vulkan_info.fDrawBounds->extent.height = mClip.fBottom - mClip.fTop;
|
|
}
|
|
|
|
VkFunctorDrawable::~VkFunctorDrawable() {}
|
|
|
|
void VkFunctorDrawable::onDraw(SkCanvas* canvas) {
|
|
// "canvas" is either SkNWayCanvas created by SkiaPipeline::tryCapture (SKP capture use case) or
|
|
// AlphaFilterCanvas (used by RenderNodeDrawable to apply alpha in certain cases).
|
|
// "VkFunctorDrawable::onDraw" is not invoked for the most common case, when drawing in a GPU
|
|
// canvas.
|
|
|
|
if (canvas->recordingContext() == nullptr) {
|
|
// We're dumping a picture, render a light-blue rectangle instead
|
|
SkPaint paint;
|
|
paint.setColor(0xFF81D4FA);
|
|
canvas->drawRect(mBounds, paint);
|
|
} else {
|
|
// Handle the case when "canvas" is AlphaFilterCanvas. Find the wrapped GPU canvas.
|
|
SkCanvas* gpuCanvas = SkAndroidFrameworkUtils::getBaseWrappedCanvas(canvas);
|
|
// Enforce "canvas" must be an AlphaFilterCanvas. For GPU canvas, the call should come from
|
|
// onSnapGpuDrawHandler.
|
|
LOG_ALWAYS_FATAL_IF(gpuCanvas == canvas,
|
|
"VkFunctorDrawable::onDraw() should not be called with a GPU canvas!");
|
|
|
|
// This will invoke onSnapGpuDrawHandler and regular draw flow.
|
|
gpuCanvas->drawDrawable(this);
|
|
}
|
|
}
|
|
|
|
std::unique_ptr<FunctorDrawable::GpuDrawHandler> VkFunctorDrawable::onSnapGpuDrawHandler(
|
|
GrBackendApi backendApi, const SkMatrix& matrix, const SkIRect& clip,
|
|
const SkImageInfo& image_info) {
|
|
if (backendApi != GrBackendApi::kVulkan) {
|
|
return nullptr;
|
|
}
|
|
std::unique_ptr<VkFunctorDrawHandler> draw;
|
|
return std::make_unique<VkFunctorDrawHandler>(mWebViewHandle, matrix, clip, image_info);
|
|
}
|
|
|
|
} // namespace skiapipeline
|
|
} // namespace uirenderer
|
|
} // namespace android
|