diff options
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/hwui/RecordingCanvas.cpp | 18 | ||||
| -rw-r--r-- | libs/hwui/RecordingCanvas.h | 31 | ||||
| -rw-r--r-- | libs/hwui/RenderProperties.h | 8 | ||||
| -rw-r--r-- | libs/hwui/SkiaCanvas.cpp | 5 | ||||
| -rw-r--r-- | libs/hwui/pipeline/skia/SkiaDisplayList.cpp | 1 | ||||
| -rw-r--r-- | libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp | 8 | ||||
| -rw-r--r-- | libs/hwui/private/hwui/DrawVkInfo.h | 2 | ||||
| -rw-r--r-- | libs/hwui/renderthread/VulkanManager.cpp | 12 | ||||
| -rw-r--r-- | libs/hwui/renderthread/VulkanManager.h | 2 |
9 files changed, 71 insertions, 16 deletions
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp index 6dc9d34cc3fd..85947665839a 100644 --- a/libs/hwui/RecordingCanvas.cpp +++ b/libs/hwui/RecordingCanvas.cpp @@ -759,6 +759,8 @@ RecordingCanvas::RecordingCanvas() : INHERITED(1, 1), fDL(nullptr) {} void RecordingCanvas::reset(DisplayListData* dl, const SkIRect& bounds) { this->resetCanvas(bounds.right(), bounds.bottom()); fDL = dl; + mClipMayBeComplex = false; + mSaveCount = mComplexSaveCount = 0; } sk_sp<SkSurface> RecordingCanvas::onNewSurface(const SkImageInfo&, const SkSurfaceProps&) { @@ -770,6 +772,7 @@ void RecordingCanvas::onFlush() { } void RecordingCanvas::willSave() { + mSaveCount++; fDL->save(); } SkCanvas::SaveLayerStrategy RecordingCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) { @@ -778,6 +781,11 @@ SkCanvas::SaveLayerStrategy RecordingCanvas::getSaveLayerStrategy(const SaveLaye return SkCanvas::kNoLayer_SaveLayerStrategy; } void RecordingCanvas::willRestore() { + mSaveCount--; + if (mSaveCount < mComplexSaveCount) { + mClipMayBeComplex = false; + mComplexSaveCount = 0; + } fDL->restore(); } @@ -798,17 +806,27 @@ void RecordingCanvas::didTranslate(SkScalar dx, SkScalar dy) { void RecordingCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle style) { fDL->clipRect(rect, op, style == kSoft_ClipEdgeStyle); + if (!getTotalMatrix().isScaleTranslate()) { + setClipMayBeComplex(); + } this->INHERITED::onClipRect(rect, op, style); } void RecordingCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle style) { + if (rrect.getType() > SkRRect::kRect_Type || !getTotalMatrix().isScaleTranslate()) { + setClipMayBeComplex(); + } fDL->clipRRect(rrect, op, style == kSoft_ClipEdgeStyle); this->INHERITED::onClipRRect(rrect, op, style); } void RecordingCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle style) { + setClipMayBeComplex(); fDL->clipPath(path, op, style == kSoft_ClipEdgeStyle); this->INHERITED::onClipPath(path, op, style); } void RecordingCanvas::onClipRegion(const SkRegion& region, SkClipOp op) { + if (region.isComplex() || !getTotalMatrix().isScaleTranslate()) { + setClipMayBeComplex(); + } fDL->clipRegion(region, op); this->INHERITED::onClipRegion(region, op); } diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h index caaef67f724f..3a76ca1137a5 100644 --- a/libs/hwui/RecordingCanvas.h +++ b/libs/hwui/RecordingCanvas.h @@ -203,10 +203,41 @@ public: void drawVectorDrawable(VectorDrawableRoot* tree); + /** + * If "isClipMayBeComplex" returns false, it is guaranteed the current clip is a rectangle. + * If the return value is true, then clip may or may not be complex (there is no guarantee). + */ + inline bool isClipMayBeComplex() { return mClipMayBeComplex; } + private: typedef SkCanvasVirtualEnforcer<SkNoDrawCanvas> INHERITED; + inline void setClipMayBeComplex() { + if (!mClipMayBeComplex) { + mComplexSaveCount = mSaveCount; + mClipMayBeComplex = true; + } + } + DisplayListData* fDL; + + /** + * mClipMayBeComplex tracks if the current clip is a rectangle. This flag is used to promote + * FunctorDrawable to a layer, if it is clipped by a non-rect. + */ + bool mClipMayBeComplex = false; + + /** + * mSaveCount is the current level of our save tree. + */ + int mSaveCount = 0; + + /** + * mComplexSaveCount is the first save level, which has a complex clip. Every level below + * mComplexSaveCount is assumed to have a complex clip and every level above mComplexSaveCount + * is guaranteed to not be complex. + */ + int mComplexSaveCount = 0; }; } // namespace uirenderer diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h index ddb7e4e4ce74..e6710cc8f950 100644 --- a/libs/hwui/RenderProperties.h +++ b/libs/hwui/RenderProperties.h @@ -151,6 +151,7 @@ public: // parent may have already dictated that a descendant layer is needed bool functorsNeedLayer = ancestorDictatesFunctorsNeedLayer + || CC_UNLIKELY(isClipMayBeComplex()) // Round rect clipping forces layer for functors || CC_UNLIKELY(getOutline().willRoundRectClip()) || @@ -193,6 +194,12 @@ public: bool isProjectionReceiver() const { return mPrimitiveFields.mProjectionReceiver; } + bool setClipMayBeComplex(bool isClipMayBeComplex) { + return RP_SET(mPrimitiveFields.mClipMayBeComplex, isClipMayBeComplex); + } + + bool isClipMayBeComplex() const { return mPrimitiveFields.mClipMayBeComplex; } + bool setStaticMatrix(const SkMatrix* matrix) { delete mStaticMatrix; if (matrix) { @@ -563,6 +570,7 @@ private: bool mProjectBackwards = false; bool mProjectionReceiver = false; bool mAllowForceDark = true; + bool mClipMayBeComplex = false; Rect mClipBounds; Outline mOutline; RevealClip mRevealClip; diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp index 54a91f4ec06f..f328a5399cbb 100644 --- a/libs/hwui/SkiaCanvas.cpp +++ b/libs/hwui/SkiaCanvas.cpp @@ -694,11 +694,8 @@ void SkiaCanvas::drawGlyphs(ReadGlyphFunc glyphFunc, int count, const Paint& pai paintCopy.setStyle(SkPaint::kFill_Style); } - SkRect bounds = - SkRect::MakeLTRB(boundsLeft + x, boundsTop + y, boundsRight + x, boundsBottom + y); - SkTextBlobBuilder builder; - const SkTextBlobBuilder::RunBuffer& buffer = builder.allocRunPos(font, count, &bounds); + const SkTextBlobBuilder::RunBuffer& buffer = builder.allocRunPos(font, count); glyphFunc(buffer.glyphs, buffer.pos); sk_sp<SkTextBlob> textBlob(builder.make()); diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp index 230065c222a9..29d5ef233338 100644 --- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp +++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp @@ -73,7 +73,6 @@ bool SkiaDisplayList::prepareListAndChildren( RenderNode* childNode = child.getRenderNode(); Matrix4 mat4(child.getRecordedMatrix()); info.damageAccumulator->pushTransform(&mat4); - // TODO: a layer is needed if the canvas is rotated or has a non-rect clip info.hasBackwardProjectedNodes = false; childFn(childNode, observer, info, functorsNeedLayer); hasBackwardProjectedNodesSubtree |= info.hasBackwardProjectedNodes; diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp index d54275fe7e19..d9456355cb88 100644 --- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp +++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp @@ -113,6 +113,10 @@ void SkiaRecordingCanvas::drawRenderNode(uirenderer::RenderNode* renderNode) { // Record the child node. Drawable dtor will be invoked when mChildNodes deque is cleared. mDisplayList->mChildNodes.emplace_back(renderNode, asSkCanvas(), true, mCurrentBarrier); auto& renderNodeDrawable = mDisplayList->mChildNodes.back(); + if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) { + // Put Vulkan WebViews with non-rectangular clips in a HW layer + renderNode->mutateStagingProperties().setClipMayBeComplex(mRecorder.isClipMayBeComplex()); + } drawDrawable(&renderNodeDrawable); // use staging property, since recording on UI thread @@ -138,10 +142,8 @@ void SkiaRecordingCanvas::callDrawGLFunction(Functor* functor, void SkiaRecordingCanvas::drawWebViewFunctor(int functor) { FunctorDrawable* functorDrawable; if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) { - // TODO(cblume) use VkFunctorDrawable instead of VkInteropFunctorDrawable here when the - // interop is disabled. functorDrawable = - mDisplayList->allocateDrawable<VkInteropFunctorDrawable>(functor, asSkCanvas()); + mDisplayList->allocateDrawable<VkFunctorDrawable>(functor, asSkCanvas()); } else { functorDrawable = mDisplayList->allocateDrawable<GLFunctorDrawable>(functor, asSkCanvas()); } diff --git a/libs/hwui/private/hwui/DrawVkInfo.h b/libs/hwui/private/hwui/DrawVkInfo.h index abc4dbf9fa1c..fb55f5ca4c93 100644 --- a/libs/hwui/private/hwui/DrawVkInfo.h +++ b/libs/hwui/private/hwui/DrawVkInfo.h @@ -29,7 +29,7 @@ struct VkFunctorInitParams { VkDevice device; VkQueue queue; uint32_t graphics_queue_index; - uint32_t instance_version; + uint32_t api_version; const char* const* enabled_instance_extension_names; uint32_t enabled_instance_extension_names_length; const char* const* enabled_device_extension_names; diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp index 1e7520216d66..582d51e6af94 100644 --- a/libs/hwui/renderthread/VulkanManager.cpp +++ b/libs/hwui/renderthread/VulkanManager.cpp @@ -83,7 +83,6 @@ void VulkanManager::destroy() { mDevice = VK_NULL_HANDLE; mPhysicalDevice = VK_NULL_HANDLE; mInstance = VK_NULL_HANDLE; - mInstanceVersion = 0u; mInstanceExtensions.clear(); mDeviceExtensions.clear(); free_features_extensions_structs(mPhysicalDeviceFeatures2); @@ -100,7 +99,7 @@ bool VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe 0, // applicationVersion "android framework", // pEngineName 0, // engineVerison - VK_MAKE_VERSION(1, 1, 0), // apiVersion + mAPIVersion, // apiVersion }; { @@ -377,8 +376,9 @@ void VulkanManager::initialize() { } GET_PROC(EnumerateInstanceVersion); - LOG_ALWAYS_FATAL_IF(mEnumerateInstanceVersion(&mInstanceVersion)); - LOG_ALWAYS_FATAL_IF(mInstanceVersion < VK_MAKE_VERSION(1, 1, 0)); + uint32_t instanceVersion; + LOG_ALWAYS_FATAL_IF(mEnumerateInstanceVersion(&instanceVersion)); + LOG_ALWAYS_FATAL_IF(instanceVersion < VK_MAKE_VERSION(1, 1, 0)); GrVkExtensions extensions; LOG_ALWAYS_FATAL_IF(!this->setupDevice(extensions, mPhysicalDeviceFeatures2)); @@ -398,7 +398,7 @@ void VulkanManager::initialize() { backendContext.fDevice = mDevice; backendContext.fQueue = mGraphicsQueue; backendContext.fGraphicsQueueIndex = mGraphicsQueueIndex; - backendContext.fInstanceVersion = mInstanceVersion; + backendContext.fMaxAPIVersion = mAPIVersion; backendContext.fVkExtensions = &extensions; backendContext.fDeviceFeatures2 = &mPhysicalDeviceFeatures2; backendContext.fGetProc = std::move(getProc); @@ -446,7 +446,7 @@ VkFunctorInitParams VulkanManager::getVkFunctorInitParams() const { .device = mDevice, .queue = mGraphicsQueue, .graphics_queue_index = mGraphicsQueueIndex, - .instance_version = mInstanceVersion, + .api_version = mAPIVersion, .enabled_instance_extension_names = mInstanceExtensions.data(), .enabled_instance_extension_names_length = static_cast<uint32_t>(mInstanceExtensions.size()), diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h index abe78efc9174..6426fe2808b7 100644 --- a/libs/hwui/renderthread/VulkanManager.h +++ b/libs/hwui/renderthread/VulkanManager.h @@ -246,7 +246,7 @@ private: VkCommandBuffer mDummyCB = VK_NULL_HANDLE; // Variables saved to populate VkFunctorInitParams. - uint32_t mInstanceVersion = 0u; + static const uint32_t mAPIVersion = VK_MAKE_VERSION(1, 1, 0); std::vector<const char*> mInstanceExtensions; std::vector<const char*> mDeviceExtensions; VkPhysicalDeviceFeatures2 mPhysicalDeviceFeatures2{}; |