diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp index 9b1f25986d565..99988542d619a 100644 --- a/libs/hwui/Properties.cpp +++ b/libs/hwui/Properties.cpp @@ -17,8 +17,8 @@ #include "Properties.h" #include "Debug.h" #include "DeviceInfo.h" -#include "SkTraceEventCommon.h" #include "HWUIProperties.sysprop.h" +#include "SkTraceEventCommon.h" #include #include @@ -67,7 +67,7 @@ bool Properties::debuggingEnabled = false; bool Properties::isolatedProcess = false; int Properties::contextPriority = 0; -int Properties::defaultRenderAhead = 0; +uint32_t Properties::defaultRenderAhead = 0; static int property_get_int(const char* key, int defaultValue) { char buf[PROPERTY_VALUE_MAX] = { @@ -130,12 +130,9 @@ bool Properties::load() { enableForceDarkSupport = property_get_bool(PROPERTY_ENABLE_FORCE_DARK, true); - defaultRenderAhead = std::max(0, std::min(2, property_get_int(PROPERTY_RENDERAHEAD, - render_ahead().value_or(0)))); - - if (defaultRenderAhead && sRenderPipelineType == RenderPipelineType::SkiaVulkan) { - ALOGW("hwui.render_ahead of %d ignored because pipeline is skiavk", defaultRenderAhead); - } + defaultRenderAhead = + std::max(0u, std::min(2u, static_cast(property_get_int( + PROPERTY_RENDERAHEAD, render_ahead().value_or(0))))); return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw); } diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index 3e91c63fcbde8..3105e58362ec0 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -253,7 +253,7 @@ public: ANDROID_API static int contextPriority; - static int defaultRenderAhead; + static uint32_t defaultRenderAhead; private: static ProfileType sProfileType; diff --git a/libs/hwui/pipeline/skia/ShaderCache.cpp b/libs/hwui/pipeline/skia/ShaderCache.cpp index 8508274676fdc..66aa8c2037991 100644 --- a/libs/hwui/pipeline/skia/ShaderCache.cpp +++ b/libs/hwui/pipeline/skia/ShaderCache.cpp @@ -15,6 +15,7 @@ */ #include "ShaderCache.h" +#include #include #include #include @@ -23,7 +24,6 @@ #include "FileBlobCache.h" #include "Properties.h" #include "utils/TraceUtils.h" -#include namespace android { namespace uirenderer { diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp index 570e895a012d5..9248eadbd0ef9 100644 --- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp @@ -101,7 +101,7 @@ bool SkiaOpenGLPipeline::draw(const Frame& frame, const SkRect& screenDirty, con SkiaPipeline::updateLighting(lightGeometry, lightInfo); renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface, - SkMatrix::I()); + SkMatrix::I()); layerUpdateQueue->clear(); // Draw visual debugging features @@ -156,8 +156,23 @@ void SkiaOpenGLPipeline::onStop() { } } +static void setBufferCount(ANativeWindow* window, uint32_t extraBuffers) { + int query_value; + int err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value); + if (err != 0 || query_value < 0) { + ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, query_value); + return; + } + auto min_undequeued_buffers = static_cast(query_value); + + int bufferCount = min_undequeued_buffers + 2 + extraBuffers; + ALOGD("Setting buffer count to %d, min_undequeued %u, extraBuffers %u", + bufferCount, min_undequeued_buffers, extraBuffers); + native_window_set_buffer_count(window, bufferCount); +} + bool SkiaOpenGLPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior, - ColorMode colorMode) { + ColorMode colorMode, uint32_t extraBuffers) { if (mEglSurface != EGL_NO_SURFACE) { mEglManager.destroySurface(mEglSurface); mEglSurface = EGL_NO_SURFACE; @@ -177,6 +192,7 @@ bool SkiaOpenGLPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBeh if (mEglSurface != EGL_NO_SURFACE) { const bool preserveBuffer = (swapBehavior != SwapBehavior::kSwap_discardBuffer); mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer); + setBufferCount(surface, extraBuffers); return true; } diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h index 66929226a5e27..3fe0f92b19247 100644 --- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h +++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h @@ -44,7 +44,7 @@ public: FrameInfo* currentFrameInfo, bool* requireSwap) override; DeferredLayerUpdater* createTextureLayer() override; bool setSurface(ANativeWindow* surface, renderthread::SwapBehavior swapBehavior, - renderthread::ColorMode colorMode) override; + renderthread::ColorMode colorMode, uint32_t extraBuffers) override; void onStop() override; bool isSurfaceReady() override; bool isContextReady() override; diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp index 721a115c13811..ccc1701dcc0b3 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp @@ -250,8 +250,9 @@ SkCanvas* SkiaPipeline::tryCapture(SkSurface* surface) { } if (mCaptureSequence > 0 || mPictureCapturedCallback) { mRecorder.reset(new SkPictureRecorder()); - SkCanvas* pictureCanvas = mRecorder->beginRecording(surface->width(), surface->height(), nullptr, - SkPictureRecorder::kPlaybackDrawPicture_RecordFlag); + SkCanvas* pictureCanvas = + mRecorder->beginRecording(surface->width(), surface->height(), nullptr, + SkPictureRecorder::kPlaybackDrawPicture_RecordFlag); mNwayCanvas = std::make_unique(surface->width(), surface->height()); mNwayCanvas->addCanvas(surface->getCanvas()); mNwayCanvas->addCanvas(pictureCanvas); @@ -276,8 +277,7 @@ void SkiaPipeline::endCapture(SkSurface* surface) { if (1 == mCaptureSequence) { savePictureAsync(data, mCapturedFile); } else { - savePictureAsync(data, - mCapturedFile + "_" + std::to_string(mCaptureSequence)); + savePictureAsync(data, mCapturedFile + "_" + std::to_string(mCaptureSequence)); } mCaptureSequence--; } @@ -327,7 +327,7 @@ static Rect nodeBounds(RenderNode& node) { auto& props = node.properties(); return Rect(props.getLeft(), props.getTop(), props.getRight(), props.getBottom()); } -} +} // namespace void SkiaPipeline::renderFrameImpl(const LayerUpdateQueue& layers, const SkRect& clip, const std::vector>& nodes, bool opaque, @@ -464,10 +464,20 @@ void SkiaPipeline::setSurfaceColorProperties(ColorMode colorMode) { // (3) Requires RGBA colors (instead of BGRA). static const uint32_t kOverdrawColors[2][6] = { { - 0x00000000, 0x00000000, 0x2f2f0000, 0x2f002f00, 0x3f00003f, 0x7f00007f, + 0x00000000, + 0x00000000, + 0x2f2f0000, + 0x2f002f00, + 0x3f00003f, + 0x7f00007f, }, { - 0x00000000, 0x00000000, 0x2f2f0000, 0x4f004f4f, 0x5f50335f, 0x7f00007f, + 0x00000000, + 0x00000000, + 0x2f2f0000, + 0x4f004f4f, + 0x5f50335f, + 0x7f00007f, }, }; diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp index d9456355cb88b..5a47a2955ad94 100644 --- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp +++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp @@ -142,8 +142,7 @@ void SkiaRecordingCanvas::callDrawGLFunction(Functor* functor, void SkiaRecordingCanvas::drawWebViewFunctor(int functor) { FunctorDrawable* functorDrawable; if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) { - functorDrawable = - mDisplayList->allocateDrawable(functor, asSkCanvas()); + functorDrawable = mDisplayList->allocateDrawable(functor, asSkCanvas()); } else { functorDrawable = mDisplayList->allocateDrawable(functor, asSkCanvas()); } diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp index edde6d3e05c0a..e8cb219db320b 100644 --- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp @@ -18,12 +18,12 @@ #include "DeferredLayerUpdater.h" #include "Readback.h" +#include "ShaderCache.h" #include "SkiaPipeline.h" #include "SkiaProfileRenderer.h" #include "VkInteropFunctorDrawable.h" #include "renderstate/RenderState.h" #include "renderthread/Frame.h" -#include "ShaderCache.h" #include #include @@ -70,8 +70,8 @@ bool SkiaVulkanPipeline::draw(const Frame& frame, const SkRect& screenDirty, con return false; } SkiaPipeline::updateLighting(lightGeometry, lightInfo); - renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, - backBuffer, mVkSurface->getCurrentPreTransform()); + renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, backBuffer, + mVkSurface->getCurrentPreTransform()); ShaderCache::get().onVkFrameFlushed(mRenderThread.getGrContext()); layerUpdateQueue->clear(); @@ -116,7 +116,7 @@ DeferredLayerUpdater* SkiaVulkanPipeline::createTextureLayer() { void SkiaVulkanPipeline::onStop() {} bool SkiaVulkanPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior, - ColorMode colorMode) { + ColorMode colorMode, uint32_t extraBuffers) { if (mVkSurface) { mVkManager.destroySurface(mVkSurface); mVkSurface = nullptr; @@ -125,8 +125,9 @@ bool SkiaVulkanPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBeh setSurfaceColorProperties(colorMode); if (surface) { mRenderThread.requireVkContext(); - mVkSurface = mVkManager.createSurface(surface, colorMode, mSurfaceColorSpace, - mSurfaceColorType, mRenderThread.getGrContext()); + mVkSurface = + mVkManager.createSurface(surface, colorMode, mSurfaceColorSpace, mSurfaceColorType, + mRenderThread.getGrContext(), extraBuffers); } return mVkSurface != nullptr; diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h index 77a7ab171ee18..31734783de7f9 100644 --- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h +++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h @@ -43,7 +43,7 @@ public: FrameInfo* currentFrameInfo, bool* requireSwap) override; DeferredLayerUpdater* createTextureLayer() override; bool setSurface(ANativeWindow* surface, renderthread::SwapBehavior swapBehavior, - renderthread::ColorMode colorMode) override; + renderthread::ColorMode colorMode, uint32_t extraBuffers) override; void onStop() override; bool isSurfaceReady() override; bool isContextReady() override; diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp index 1b9e53b21adb5..112792611fc3f 100644 --- a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp +++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp @@ -17,16 +17,16 @@ #include "VkFunctorDrawable.h" #include -#include "renderthread/VulkanManager.h" -#include "renderthread/RenderThread.h" -#include #include +#include #include #include #include #include #include #include +#include "renderthread/RenderThread.h" +#include "renderthread/VulkanManager.h" #include "thread/ThreadBase.h" #include "utils/TimeUtils.h" @@ -64,13 +64,13 @@ void VkFunctorDrawHandler::draw(const GrBackendDrawableInfo& info) { SkMatrix44 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, + .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.asColMajorf(¶ms.transform[0]); params.secondary_command_buffer = vulkan_info.fSecondaryCommandBuffer; @@ -87,8 +87,7 @@ void VkFunctorDrawHandler::draw(const GrBackendDrawableInfo& info) { vulkan_info.fDrawBounds->extent.height = mClip.fBottom - mClip.fTop; } -VkFunctorDrawable::~VkFunctorDrawable() { -} +VkFunctorDrawable::~VkFunctorDrawable() {} void VkFunctorDrawable::onDraw(SkCanvas* canvas) { // "canvas" is either SkNWayCanvas created by SkiaPipeline::tryCapture (SKP capture use case) or @@ -106,9 +105,8 @@ void VkFunctorDrawable::onDraw(SkCanvas* 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!"); + 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); diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp index 8b02c11911ca4..a31081c9a4514 100644 --- a/libs/hwui/renderthread/CacheManager.cpp +++ b/libs/hwui/renderthread/CacheManager.cpp @@ -21,17 +21,16 @@ #include "RenderThread.h" #include "pipeline/skia/ShaderCache.h" #include "pipeline/skia/SkiaMemoryTracer.h" -#include "Properties.h" #include "renderstate/RenderState.h" #include "thread/CommonPool.h" #include #include #include +#include #include #include #include -#include namespace android { namespace uirenderer { @@ -79,14 +78,13 @@ void CacheManager::updateContextCacheSizes() { class CommonPoolExecutor : public SkExecutor { public: - virtual void add(std::function func) override { - CommonPool::post(std::move(func)); - } + virtual void add(std::function func) override { CommonPool::post(std::move(func)); } }; static CommonPoolExecutor sDefaultExecutor; -void CacheManager::configureContext(GrContextOptions* contextOptions, const void* identity, ssize_t size) { +void CacheManager::configureContext(GrContextOptions* contextOptions, const void* identity, + ssize_t size) { contextOptions->fAllowPathMaskCaching = true; // This sets the maximum size for a single texture atlas in the GPU font cache. If necessary, @@ -180,7 +178,8 @@ void CacheManager::dumpMemoryUsage(String8& log, const RenderState* renderState) } const char* layerType = Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL - ? "GlLayer" : "VkLayer"; + ? "GlLayer" + : "VkLayer"; size_t layerMemoryTotal = 0; for (std::set::iterator it = renderState->mActiveLayers.begin(); it != renderState->mActiveLayers.end(); it++) { diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 4808d68b89ab6..1b3bd302fba9b 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -17,6 +17,7 @@ #include "CanvasContext.h" #include +#include "../Properties.h" #include "AnimationContext.h" #include "EglManager.h" #include "Frame.h" @@ -31,7 +32,6 @@ #include "utils/GLUtils.h" #include "utils/TimeUtils.h" #include "utils/TraceUtils.h" -#include "../Properties.h" #include #include @@ -153,7 +153,8 @@ void CanvasContext::setSurface(sp&& surface) { } ColorMode colorMode = mWideColorGamut ? ColorMode::WideColorGamut : ColorMode::SRGB; - bool hasSurface = mRenderPipeline->setSurface(mNativeSurface.get(), mSwapBehavior, colorMode); + bool hasSurface = mRenderPipeline->setSurface(mNativeSurface.get(), mSwapBehavior, colorMode, + mRenderAheadDepth); mFrameNumber = -1; @@ -298,7 +299,7 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t sy mAnimationContext->startFrame(info.mode); mRenderPipeline->onPrepareTree(); - for (const sp &node : mRenderNodes) { + for (const sp& node : mRenderNodes) { // Only the primary target node will be drawn full - all other nodes would get drawn in // real time mode. In case of a window, the primary node is the window content and the other // node(s) are non client / filler nodes. @@ -322,7 +323,7 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t sy if (CC_LIKELY(mSwapHistory.size() && !Properties::forceDrawFrame)) { nsecs_t latestVsync = mRenderThread.timeLord().latestVsync(); - SwapHistory &lastSwap = mSwapHistory.back(); + SwapHistory& lastSwap = mSwapHistory.back(); nsecs_t vsyncDelta = std::abs(lastSwap.vsyncTime - latestVsync); // The slight fudge-factor is to deal with cases where // the vsync was estimated due to being slow handling the signal. @@ -405,8 +406,7 @@ void CanvasContext::draw() { SkRect dirty; mDamageAccumulator.finish(&dirty); - if (dirty.isEmpty() && Properties::skipEmptyFrames - && !surfaceRequiresRedraw()) { + if (dirty.isEmpty() && Properties::skipEmptyFrames && !surfaceRequiresRedraw()) { mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame); return; } @@ -416,21 +416,21 @@ void CanvasContext::draw() { Frame frame = mRenderPipeline->getFrame(); SkRect windowDirty = computeDirtyRect(frame, &dirty); + if (mRenderAheadDepth) { + auto presentTime = + mCurrentFrameInfo->get(FrameInfoIndex::Vsync) + + (mRenderThread.timeLord().frameIntervalNanos() * (mRenderAheadDepth + 1)); + native_window_set_buffers_timestamp(mNativeSurface.get(), presentTime); + } bool drew = mRenderPipeline->draw(frame, windowDirty, dirty, mLightGeometry, &mLayerUpdateQueue, - mContentDrawBounds, mOpaque, mLightInfo, - mRenderNodes, &(profiler())); + mContentDrawBounds, mOpaque, mLightInfo, mRenderNodes, + &(profiler())); int64_t frameCompleteNr = mFrameCompleteCallbacks.size() ? getFrameNumber() : -1; waitOnFences(); - if (mRenderAheadDepth) { - auto presentTime = mCurrentFrameInfo->get(FrameInfoIndex::Vsync) + - (mRenderThread.timeLord().frameIntervalNanos() * (mRenderAheadDepth + 1)); - native_window_set_buffers_timestamp(mNativeSurface.get(), presentTime); - } - bool requireSwap = false; bool didSwap = mRenderPipeline->swapBuffers(frame, drew, windowDirty, mCurrentFrameInfo, &requireSwap); @@ -645,21 +645,13 @@ bool CanvasContext::surfaceRequiresRedraw() { } void CanvasContext::applyRenderAheadSettings() { - if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) { - // TODO: Fix SkiaVulkan's assumptions on buffer counts. And SIGBUS crashes. - mRenderAheadDepth = 0; - return; - } - if (mNativeSurface) { - native_window_set_buffer_count(mNativeSurface.get(), 3 + mRenderAheadDepth); - if (!mRenderAheadDepth) { - native_window_set_buffers_timestamp(mNativeSurface.get(), NATIVE_WINDOW_TIMESTAMP_AUTO); - } + if (mNativeSurface && !mRenderAheadDepth) { + native_window_set_buffers_timestamp(mNativeSurface.get(), NATIVE_WINDOW_TIMESTAMP_AUTO); } } -void CanvasContext::setRenderAheadDepth(int renderAhead) { - if (renderAhead < 0 || renderAhead > 2 || renderAhead == mRenderAheadDepth) { +void CanvasContext::setRenderAheadDepth(uint32_t renderAhead) { + if (renderAhead > 2 || renderAhead == mRenderAheadDepth || mNativeSurface) { return; } mRenderAheadDepth = renderAhead; diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 4a3119a55c77e..0bd080d4d7e40 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -17,15 +17,15 @@ #pragma once #include "DamageAccumulator.h" -#include "Lighting.h" #include "FrameInfo.h" #include "FrameInfoVisualizer.h" #include "FrameMetricsReporter.h" #include "IContextFactory.h" #include "IRenderPipeline.h" #include "LayerUpdateQueue.h" -#include "RenderNode.h" +#include "Lighting.h" #include "ReliableSurface.h" +#include "RenderNode.h" #include "renderthread/RenderTask.h" #include "renderthread/RenderThread.h" @@ -37,10 +37,10 @@ #include #include +#include #include #include #include -#include namespace android { namespace uirenderer { @@ -187,9 +187,7 @@ public: mRenderPipeline->setPictureCapturedCallback(callback); } - void setForceDark(bool enable) { - mUseForceDark = enable; - } + void setForceDark(bool enable) { mUseForceDark = enable; } bool useForceDark() { // The force-dark override has the highest priority, followed by the disable setting @@ -204,7 +202,8 @@ public: return mUseForceDark; } - void setRenderAheadDepth(int renderAhead); + // Must be called before setSurface + void setRenderAheadDepth(uint32_t renderAhead); private: CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode, @@ -238,7 +237,7 @@ private: // painted onto its surface. bool mIsDirty = false; SwapBehavior mSwapBehavior = SwapBehavior::kSwap_default; - int mRenderAheadDepth = 0; + uint32_t mRenderAheadDepth = 0; struct SwapHistory { SkRect damage; nsecs_t vsyncTime; diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp index 51eeab7e46ce7..91dc3bc6e603c 100644 --- a/libs/hwui/renderthread/DrawFrameTask.cpp +++ b/libs/hwui/renderthread/DrawFrameTask.cpp @@ -109,9 +109,8 @@ void DrawFrameTask::run() { // Even if we aren't drawing this vsync pulse the next frame number will still be accurate if (CC_UNLIKELY(callback)) { - context->enqueueFrameWork([callback, frameNr = context->getFrameNumber()]() { - callback(frameNr); - }); + context->enqueueFrameWork( + [callback, frameNr = context->getFrameNumber()]() { callback(frameNr); }); } if (CC_LIKELY(canDrawThisFrame)) { diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp index 2cc3f362e172d..1d553342415cb 100644 --- a/libs/hwui/renderthread/EglManager.cpp +++ b/libs/hwui/renderthread/EglManager.cpp @@ -29,10 +29,10 @@ #include #include +#include +#include #include #include -#include -#include #define GLES_VERSION 2 @@ -171,8 +171,7 @@ EGLConfig EglManager::load8BitsConfig(EGLDisplay display, EglManager::SwapBehavi EGL_NONE}; EGLConfig config = EGL_NO_CONFIG_KHR; EGLint numConfigs = 1; - if (!eglChooseConfig(display, attribs, &config, numConfigs, &numConfigs) || - numConfigs != 1) { + if (!eglChooseConfig(display, attribs, &config, numConfigs, &numConfigs) || numConfigs != 1) { return EGL_NO_CONFIG_KHR; } return config; @@ -203,8 +202,7 @@ EGLConfig EglManager::loadFP16Config(EGLDisplay display, SwapBehavior swapBehavi EGL_NONE}; EGLConfig config = EGL_NO_CONFIG_KHR; EGLint numConfigs = 1; - if (!eglChooseConfig(display, attribs, &config, numConfigs, &numConfigs) || - numConfigs != 1) { + if (!eglChooseConfig(display, attribs, &config, numConfigs, &numConfigs) || numConfigs != 1) { return EGL_NO_CONFIG_KHR; } return config; @@ -262,7 +260,7 @@ void EglManager::loadConfigs() { mEglConfigWideGamut = loadFP16Config(mEglDisplay, mSwapBehavior); if (mEglConfigWideGamut == EGL_NO_CONFIG_KHR) { ALOGE("Device claims wide gamut support, cannot find matching config, error = %s", - eglErrorString()); + eglErrorString()); EglExtensions.pixelFormatFloat = false; } } else if (wideColorType == SkColorType::kN32_SkColorType) { @@ -350,7 +348,7 @@ Result EglManager::createSurface(EGLNativeWindowType window, EGLSurface surface = eglCreateWindowSurface( mEglDisplay, wideColorGamut ? mEglConfigWideGamut : mEglConfig, window, attribs); if (surface == EGL_NO_SURFACE) { - return Error { eglGetError() }; + return Error{eglGetError()}; } if (mSwapBehavior != SwapBehavior::Preserved) { @@ -525,12 +523,8 @@ status_t EglManager::fenceWait(sp& fence) { ALOGE("EglManager::fenceWait: error dup'ing fence fd: %d", errno); return -errno; } - EGLint attribs[] = { - EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd, - EGL_NONE - }; - EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay, - EGL_SYNC_NATIVE_FENCE_ANDROID, attribs); + EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd, EGL_NONE}; + EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs); if (sync == EGL_NO_SYNC_KHR) { close(fenceFd); ALOGE("EglManager::fenceWait: error creating EGL fence: %#x", eglGetError()); @@ -559,18 +553,16 @@ status_t EglManager::fenceWait(sp& fence) { } status_t EglManager::createReleaseFence(bool useFenceSync, EGLSyncKHR* eglFence, - sp& nativeFence) { + sp& nativeFence) { if (!hasEglContext()) { ALOGE("EglManager::createReleaseFence: EGLDisplay not initialized"); return INVALID_OPERATION; } if (SyncFeatures::getInstance().useNativeFenceSync()) { - EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay, - EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr); + EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr); if (sync == EGL_NO_SYNC_KHR) { - ALOGE("EglManager::createReleaseFence: error creating EGL fence: %#x", - eglGetError()); + ALOGE("EglManager::createReleaseFence: error creating EGL fence: %#x", eglGetError()); return UNKNOWN_ERROR; } glFlush(); @@ -578,7 +570,8 @@ status_t EglManager::createReleaseFence(bool useFenceSync, EGLSyncKHR* eglFence, eglDestroySyncKHR(mEglDisplay, sync); if (fenceFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { ALOGE("EglManager::createReleaseFence: error dup'ing native fence " - "fd: %#x", eglGetError()); + "fd: %#x", + eglGetError()); return UNKNOWN_ERROR; } nativeFence = new Fence(fenceFd); @@ -592,7 +585,7 @@ status_t EglManager::createReleaseFence(bool useFenceSync, EGLSyncKHR* eglFence, EGLint result = eglClientWaitSyncKHR(mEglDisplay, *eglFence, 0, 1000000000); if (result == EGL_FALSE) { ALOGE("EglManager::createReleaseFence: error waiting for previous fence: %#x", - eglGetError()); + eglGetError()); return UNKNOWN_ERROR; } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { ALOGE("EglManager::createReleaseFence: timeout waiting for previous fence"); diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h index 0502eb88b6a56..3b81014c05e24 100644 --- a/libs/hwui/renderthread/IRenderPipeline.h +++ b/libs/hwui/renderthread/IRenderPipeline.h @@ -66,8 +66,8 @@ public: virtual bool swapBuffers(const Frame& frame, bool drew, const SkRect& screenDirty, FrameInfo* currentFrameInfo, bool* requireSwap) = 0; virtual DeferredLayerUpdater* createTextureLayer() = 0; - virtual bool setSurface(ANativeWindow* window, SwapBehavior swapBehavior, - ColorMode colorMode) = 0; + virtual bool setSurface(ANativeWindow* window, SwapBehavior swapBehavior, ColorMode colorMode, + uint32_t extraBuffers) = 0; virtual void onStop() = 0; virtual bool isSurfaceReady() = 0; virtual bool isContextReady() = 0; diff --git a/libs/hwui/renderthread/ReliableSurface.cpp b/libs/hwui/renderthread/ReliableSurface.cpp index 6f2b9df918e3b..b9410c24366fa 100644 --- a/libs/hwui/renderthread/ReliableSurface.cpp +++ b/libs/hwui/renderthread/ReliableSurface.cpp @@ -34,13 +34,13 @@ struct SurfaceExposer : Surface { // Make warnings happy SurfaceExposer() = delete; - using Surface::setBufferCount; - using Surface::setSwapInterval; - using Surface::dequeueBuffer; - using Surface::queueBuffer; using Surface::cancelBuffer; + using Surface::dequeueBuffer; using Surface::lockBuffer_DEPRECATED; using Surface::perform; + using Surface::queueBuffer; + using Surface::setBufferCount; + using Surface::setSwapInterval; }; #define callProtected(surface, func, ...) ((*surface).*&SurfaceExposer::func)(__VA_ARGS__) diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index b58bab1191edb..1a1b9dac37f6b 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -84,7 +84,7 @@ void RenderProxy::setName(const char* name) { void RenderProxy::setSurface(const sp& surface) { mRenderThread.queue().post( - [ this, surf = surface ]() mutable { mContext->setSurface(std::move(surf)); }); + [this, surf = surface]() mutable { mContext->setSurface(std::move(surf)); }); } void RenderProxy::allocateBuffers() { @@ -251,7 +251,7 @@ void RenderProxy::dumpGraphicsMemory(int fd) { void RenderProxy::setProcessStatsBuffer(int fd) { auto& rt = RenderThread::getInstance(); - rt.queue().post([&rt, fd = dup(fd) ]() { + rt.queue().post([&rt, fd = dup(fd)]() { rt.globalProfileData().switchStorageToAshmem(fd); close(fd); }); @@ -285,7 +285,7 @@ void RenderProxy::setContentDrawBounds(int left, int top, int right, int bottom) void RenderProxy::setPictureCapturedCallback( const std::function&&)>& callback) { mRenderThread.queue().post( - [ this, cb = callback ]() { mContext->setPictureCapturedCallback(cb); }); + [this, cb = callback]() { mContext->setPictureCapturedCallback(cb); }); } void RenderProxy::setFrameCallback(std::function&& callback) { @@ -297,13 +297,13 @@ void RenderProxy::setFrameCompleteCallback(std::function&& callba } void RenderProxy::addFrameMetricsObserver(FrameMetricsObserver* observerPtr) { - mRenderThread.queue().post([ this, observer = sp{observerPtr} ]() { + mRenderThread.queue().post([this, observer = sp{observerPtr}]() { mContext->addFrameMetricsObserver(observer.get()); }); } void RenderProxy::removeFrameMetricsObserver(FrameMetricsObserver* observerPtr) { - mRenderThread.queue().post([ this, observer = sp{observerPtr} ]() { + mRenderThread.queue().post([this, observer = sp{observerPtr}]() { mContext->removeFrameMetricsObserver(observer.get()); }); } @@ -313,9 +313,8 @@ void RenderProxy::setForceDark(bool enable) { } void RenderProxy::setRenderAheadDepth(int renderAhead) { - mRenderThread.queue().post([ context = mContext, renderAhead ] { - context->setRenderAheadDepth(renderAhead); - }); + mRenderThread.queue().post( + [context = mContext, renderAhead] { context->setRenderAheadDepth(renderAhead); }); } int RenderProxy::copySurfaceInto(sp& surface, int left, int top, int right, int bottom, @@ -393,9 +392,7 @@ void RenderProxy::releaseVDAtlasEntries() { void RenderProxy::preload() { // Create RenderThread object and start the thread. Then preload Vulkan/EGL driver. auto& thread = RenderThread::getInstance(); - thread.queue().post([&thread]() { - thread.preload(); - }); + thread.queue().post([&thread]() { thread.preload(); }); } } /* namespace renderthread */ diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index b76e49ce94a0d..eca7d88e4e48a 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -16,6 +16,7 @@ #include "RenderThread.h" +#include "../HardwareBitmapUploader.h" #include "CanvasContext.h" #include "DeviceInfo.h" #include "EglManager.h" @@ -29,7 +30,6 @@ #include "utils/FatVector.h" #include "utils/TimeUtils.h" #include "utils/TraceUtils.h" -#include "../HardwareBitmapUploader.h" #ifdef HWUI_GLES_WRAP_ENABLED #include "debug/GlesDriver.h" @@ -410,9 +410,7 @@ bool RenderThread::isCurrent() { void RenderThread::preload() { // EGL driver is always preloaded only if HWUI renders with GL. if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) { - std::thread eglInitThread([]() { - eglGetDisplay(EGL_DEFAULT_DISPLAY); - }); + std::thread eglInitThread([]() { eglGetDisplay(EGL_DEFAULT_DISPLAY); }); eglInitThread.detach(); } else { requireVkContext(); diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h index 5f43b488bcf26..6bb26fd6c6756 100644 --- a/libs/hwui/renderthread/RenderThread.h +++ b/libs/hwui/renderthread/RenderThread.h @@ -22,8 +22,8 @@ #include "../JankTracker.h" #include "CacheManager.h" #include "TimeLord.h" -#include "thread/ThreadBase.h" #include "WebViewFunctorManager.h" +#include "thread/ThreadBase.h" #include "utils/TimeUtils.h" #include diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp index 4011329fa2da1..5edf3301b2e81 100644 --- a/libs/hwui/renderthread/VulkanManager.cpp +++ b/libs/hwui/renderthread/VulkanManager.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -43,7 +42,7 @@ static void free_features_extensions_structs(const VkPhysicalDeviceFeatures2& fe // so we can get access to the pNext for the next struct. struct CommonVulkanHeader { VkStructureType sType; - void* pNext; + void* pNext; }; void* pNext = features.pNext; @@ -94,13 +93,13 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe VkResult err; constexpr VkApplicationInfo app_info = { - VK_STRUCTURE_TYPE_APPLICATION_INFO, // sType - nullptr, // pNext - "android framework", // pApplicationName - 0, // applicationVersion - "android framework", // pEngineName - 0, // engineVerison - mAPIVersion, // apiVersion + VK_STRUCTURE_TYPE_APPLICATION_INFO, // sType + nullptr, // pNext + "android framework", // pApplicationName + 0, // applicationVersion + "android framework", // pEngineName + 0, // engineVerison + mAPIVersion, // apiVersion }; { @@ -128,14 +127,14 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe } const VkInstanceCreateInfo instance_create = { - VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType - nullptr, // pNext - 0, // flags - &app_info, // pApplicationInfo - 0, // enabledLayerNameCount - nullptr, // ppEnabledLayerNames - (uint32_t) mInstanceExtensions.size(), // enabledExtensionNameCount - mInstanceExtensions.data(), // ppEnabledExtensionNames + VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType + nullptr, // pNext + 0, // flags + &app_info, // pApplicationInfo + 0, // enabledLayerNameCount + nullptr, // ppEnabledLayerNames + (uint32_t)mInstanceExtensions.size(), // enabledExtensionNameCount + mInstanceExtensions.data(), // ppEnabledExtensionNames }; GET_PROC(CreateInstance); @@ -200,11 +199,11 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe { uint32_t extensionCount = 0; err = mEnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr, &extensionCount, - nullptr); + nullptr); LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err); mDeviceExtensionsOwner.resize(extensionCount); err = mEnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr, &extensionCount, - mDeviceExtensionsOwner.data()); + mDeviceExtensionsOwner.data()); LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err); bool hasKHRSwapchainExtension = false; for (const VkExtensionProperties& extension : mDeviceExtensionsOwner) { @@ -216,7 +215,7 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe LOG_ALWAYS_FATAL_IF(!hasKHRSwapchainExtension); } - auto getProc = [] (const char* proc_name, VkInstance instance, VkDevice device) { + auto getProc = [](const char* proc_name, VkInstance instance, VkDevice device) { if (device != VK_NULL_HANDLE) { return vkGetDeviceProcAddr(device, proc_name); } @@ -224,7 +223,8 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe }; grExtensions.init(getProc, mInstance, mPhysicalDevice, mInstanceExtensions.size(), - mInstanceExtensions.data(), mDeviceExtensions.size(), mDeviceExtensions.data()); + mInstanceExtensions.data(), mDeviceExtensions.size(), + mDeviceExtensions.data()); LOG_ALWAYS_FATAL_IF(!grExtensions.hasExtension(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, 1)); @@ -237,7 +237,7 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe if (grExtensions.hasExtension(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, 2)) { VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT* blend; - blend = (VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT*) malloc( + blend = (VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT*)malloc( sizeof(VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT)); LOG_ALWAYS_FATAL_IF(!blend); blend->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT; @@ -247,7 +247,7 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe } VkPhysicalDeviceSamplerYcbcrConversionFeatures* ycbcrFeature; - ycbcrFeature = (VkPhysicalDeviceSamplerYcbcrConversionFeatures*) malloc( + ycbcrFeature = (VkPhysicalDeviceSamplerYcbcrConversionFeatures*)malloc( sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeatures)); LOG_ALWAYS_FATAL_IF(!ycbcrFeature); ycbcrFeature->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES; @@ -261,17 +261,17 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe // and we can't depend on it on all platforms features.features.robustBufferAccess = VK_FALSE; - float queuePriorities[1] = { 0.0 }; + float queuePriorities[1] = {0.0}; void* queueNextPtr = nullptr; VkDeviceQueueGlobalPriorityCreateInfoEXT queuePriorityCreateInfo; - if (Properties::contextPriority != 0 - && grExtensions.hasExtension(VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME, 2)) { + if (Properties::contextPriority != 0 && + grExtensions.hasExtension(VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME, 2)) { memset(&queuePriorityCreateInfo, 0, sizeof(VkDeviceQueueGlobalPriorityCreateInfoEXT)); queuePriorityCreateInfo.sType = - VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT; + VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT; queuePriorityCreateInfo.pNext = nullptr; switch (Properties::contextPriority) { case EGL_CONTEXT_PRIORITY_LOW_IMG: @@ -285,41 +285,40 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe break; default: LOG_ALWAYS_FATAL("Unsupported context priority"); - } - queueNextPtr = &queuePriorityCreateInfo; + } + queueNextPtr = &queuePriorityCreateInfo; } const VkDeviceQueueCreateInfo queueInfo[2] = { - { - VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType - queueNextPtr, // pNext - 0, // VkDeviceQueueCreateFlags - mGraphicsQueueIndex, // queueFamilyIndex - 1, // queueCount - queuePriorities, // pQueuePriorities - }, - { - VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType - queueNextPtr, // pNext - 0, // VkDeviceQueueCreateFlags - mPresentQueueIndex, // queueFamilyIndex - 1, // queueCount - queuePriorities, // pQueuePriorities - } - }; + { + VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType + queueNextPtr, // pNext + 0, // VkDeviceQueueCreateFlags + mGraphicsQueueIndex, // queueFamilyIndex + 1, // queueCount + queuePriorities, // pQueuePriorities + }, + { + VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType + queueNextPtr, // pNext + 0, // VkDeviceQueueCreateFlags + mPresentQueueIndex, // queueFamilyIndex + 1, // queueCount + queuePriorities, // pQueuePriorities + }}; uint32_t queueInfoCount = (mPresentQueueIndex != mGraphicsQueueIndex) ? 2 : 1; const VkDeviceCreateInfo deviceInfo = { - VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType - &features, // pNext - 0, // VkDeviceCreateFlags - queueInfoCount, // queueCreateInfoCount - queueInfo, // pQueueCreateInfos - 0, // layerCount - nullptr, // ppEnabledLayerNames - (uint32_t) mDeviceExtensions.size(), // extensionCount - mDeviceExtensions.data(), // ppEnabledExtensionNames - nullptr, // ppEnabledFeatures + VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType + &features, // pNext + 0, // VkDeviceCreateFlags + queueInfoCount, // queueCreateInfoCount + queueInfo, // pQueueCreateInfos + 0, // layerCount + nullptr, // ppEnabledLayerNames + (uint32_t)mDeviceExtensions.size(), // extensionCount + mDeviceExtensions.data(), // ppEnabledExtensionNames + nullptr, // ppEnabledFeatures }; LOG_ALWAYS_FATAL_IF(mCreateDevice(mPhysicalDevice, &deviceInfo, nullptr, &mDevice)); @@ -371,8 +370,8 @@ void VulkanManager::initialize() { // this needs to be on the render queue commandPoolInfo.queueFamilyIndex = mGraphicsQueueIndex; commandPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - SkDEBUGCODE(VkResult res =) mCreateCommandPool(mDevice, &commandPoolInfo, nullptr, - &mCommandPool); + SkDEBUGCODE(VkResult res =) + mCreateCommandPool(mDevice, &commandPoolInfo, nullptr, &mCommandPool); SkASSERT(VK_SUCCESS == res); } LOG_ALWAYS_FATAL_IF(mCommandPool == VK_NULL_HANDLE); @@ -391,7 +390,7 @@ void VulkanManager::initialize() { } sk_sp VulkanManager::createContext(const GrContextOptions& options) { - auto getProc = [] (const char* proc_name, VkInstance instance, VkDevice device) { + auto getProc = [](const char* proc_name, VkInstance instance, VkDevice device) { if (device != VK_NULL_HANDLE) { return vkGetDeviceProcAddr(device, proc_name); } @@ -431,7 +430,6 @@ VkFunctorInitParams VulkanManager::getVkFunctorInitParams() const { } Frame VulkanManager::dequeueNextBuffer(VulkanSurface* surface) { - VulkanSurface::NativeBufferInfo* bufferInfo = surface->dequeueNativeBuffer(); if (bufferInfo == nullptr) { @@ -480,7 +478,7 @@ Frame VulkanManager::dequeueNextBuffer(VulkanSurface* surface) { bufferInfo->skSurface->wait(1, &backendSemaphore); // The following flush blocks the GPU immediately instead of waiting for other // drawing ops. It seems dequeue_fence is not respected otherwise. - //TODO: remove the flush after finding why backendSemaphore is not working. + // TODO: remove the flush after finding why backendSemaphore is not working. bufferInfo->skSurface->flush(); } } @@ -557,15 +555,15 @@ void VulkanManager::destroySurface(VulkanSurface* surface) { VulkanSurface* VulkanManager::createSurface(ANativeWindow* window, ColorMode colorMode, sk_sp surfaceColorSpace, - SkColorType surfaceColorType, - GrContext* grContext) { + SkColorType surfaceColorType, GrContext* grContext, + uint32_t extraBuffers) { LOG_ALWAYS_FATAL_IF(!hasVkContext(), "Not initialized"); if (!window) { return nullptr; } return VulkanSurface::Create(window, colorMode, surfaceColorType, surfaceColorSpace, grContext, - *this); + *this, extraBuffers); } bool VulkanManager::setupDummyCommandBuffer() { diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h index a7a43cc39a458..1a3a0e4855239 100644 --- a/libs/hwui/renderthread/VulkanManager.h +++ b/libs/hwui/renderthread/VulkanManager.h @@ -18,16 +18,16 @@ #define VULKANMANAGER_H #if !defined(VK_USE_PLATFORM_ANDROID_KHR) -# define VK_USE_PLATFORM_ANDROID_KHR +#define VK_USE_PLATFORM_ANDROID_KHR #endif #include #include -#include #include #include #include #include +#include #include "Frame.h" #include "IRenderPipeline.h" #include "VulkanSurface.h" @@ -59,8 +59,8 @@ public: // Create and destroy functions for wrapping an ANativeWindow in a VulkanSurface VulkanSurface* createSurface(ANativeWindow* window, ColorMode colorMode, sk_sp surfaceColorSpace, - SkColorType surfaceColorType, - GrContext* grContext); + SkColorType surfaceColorType, GrContext* grContext, + uint32_t extraBuffers); void destroySurface(VulkanSurface* surface); Frame dequeueNextBuffer(VulkanSurface* surface); diff --git a/libs/hwui/renderthread/VulkanSurface.cpp b/libs/hwui/renderthread/VulkanSurface.cpp index 36f540c479738..447512e5db39c 100644 --- a/libs/hwui/renderthread/VulkanSurface.cpp +++ b/libs/hwui/renderthread/VulkanSurface.cpp @@ -16,12 +16,12 @@ #include "VulkanSurface.h" -#include #include +#include #include "VulkanManager.h" -#include "utils/TraceUtils.h" #include "utils/Color.h" +#include "utils/TraceUtils.h" namespace android { namespace uirenderer { @@ -31,10 +31,9 @@ static bool IsTransformSupported(int transform) { // For now, only support pure rotations, not flip or flip-and-rotate, until we have // more time to test them and build sample code. As far as I know we never actually // use anything besides pure rotations anyway. - return transform == 0 - || transform == NATIVE_WINDOW_TRANSFORM_ROT_90 - || transform == NATIVE_WINDOW_TRANSFORM_ROT_180 - || transform == NATIVE_WINDOW_TRANSFORM_ROT_270; + return transform == 0 || transform == NATIVE_WINDOW_TRANSFORM_ROT_90 || + transform == NATIVE_WINDOW_TRANSFORM_ROT_180 || + transform == NATIVE_WINDOW_TRANSFORM_ROT_270; } static int InvertTransform(int transform) { @@ -85,16 +84,16 @@ static SkMatrix GetPreTransformMatrix(SkISize windowSize, int transform) { } void VulkanSurface::ComputeWindowSizeAndTransform(WindowInfo* windowInfo, const SkISize& minSize, - const SkISize& maxSize) { + const SkISize& maxSize) { SkISize& windowSize = windowInfo->size; // clamp width & height to handle currentExtent of -1 and protect us from broken hints - if (windowSize.width() < minSize.width() || windowSize.width() > maxSize.width() - || windowSize.height() < minSize.height() || windowSize.height() > maxSize.height()) { + if (windowSize.width() < minSize.width() || windowSize.width() > maxSize.width() || + windowSize.height() < minSize.height() || windowSize.height() > maxSize.height()) { int width = std::min(maxSize.width(), std::max(minSize.width(), windowSize.width())); int height = std::min(maxSize.height(), std::max(minSize.height(), windowSize.height())); - ALOGE("Invalid Window Dimensions [%d, %d]; clamping to [%d, %d]", - windowSize.width(), windowSize.height(), width, height); + ALOGE("Invalid Window Dimensions [%d, %d]; clamping to [%d, %d]", windowSize.width(), + windowSize.height(), width, height); windowSize.set(width, height); } @@ -145,12 +144,8 @@ class VkSurfaceAutoDeleter { public: VkSurfaceAutoDeleter(VkInstance instance, VkSurfaceKHR surface, PFN_vkDestroySurfaceKHR destroySurfaceKHR) - : mInstance(instance) - , mSurface(surface) - , mDestroySurfaceKHR(destroySurfaceKHR) {} - ~VkSurfaceAutoDeleter() { - destroy(); - } + : mInstance(instance), mSurface(surface), mDestroySurfaceKHR(destroySurfaceKHR) {} + ~VkSurfaceAutoDeleter() { destroy(); } void destroy() { if (mSurface != VK_NULL_HANDLE) { @@ -166,9 +161,9 @@ private: }; VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode, - SkColorType colorType, sk_sp colorSpace, - GrContext* grContext, const VulkanManager& vkManager) { - + SkColorType colorType, sk_sp colorSpace, + GrContext* grContext, const VulkanManager& vkManager, + uint32_t extraBuffers) { VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo; memset(&surfaceCreateInfo, 0, sizeof(VkAndroidSurfaceCreateInfoKHR)); surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; @@ -188,10 +183,11 @@ VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode, vkManager.mDestroySurfaceKHR); SkDEBUGCODE(VkBool32 supported; res = vkManager.mGetPhysicalDeviceSurfaceSupportKHR( - vkManager.mPhysicalDevice, vkManager.mPresentQueueIndex, vkSurface, &supported); - // All physical devices and queue families on Android must be capable of - // presentation with any native window. - SkASSERT(VK_SUCCESS == res && supported);); + vkManager.mPhysicalDevice, vkManager.mPresentQueueIndex, + vkSurface, &supported); + // All physical devices and queue families on Android must be capable of + // presentation with any native window. + SkASSERT(VK_SUCCESS == res && supported);); // check for capabilities VkSurfaceCapabilitiesKHR caps; @@ -225,14 +221,13 @@ VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode, int query_value; int err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value); if (err != 0 || query_value < 0) { - ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, - query_value); + ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, query_value); return nullptr; } auto min_undequeued_buffers = static_cast(query_value); - windowInfo.bufferCount = min_undequeued_buffers - + std::max(VulkanSurface::sTargetBufferCount, caps.minImageCount); + windowInfo.bufferCount = min_undequeued_buffers + + std::max(sTargetBufferCount + extraBuffers, caps.minImageCount); if (caps.maxImageCount > 0 && windowInfo.bufferCount > caps.maxImageCount) { // Application must settle for fewer images than desired: windowInfo.bufferCount = caps.maxImageCount; @@ -241,8 +236,7 @@ VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode, // Currently Skia requires the images to be color attachments and support all transfer // operations. VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | - VK_IMAGE_USAGE_SAMPLED_BIT | - VK_IMAGE_USAGE_TRANSFER_SRC_BIT | + VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; LOG_ALWAYS_FATAL_IF((caps.supportedUsageFlags & usageFlags) != usageFlags); @@ -337,7 +331,8 @@ bool VulkanSurface::UpdateWindow(ANativeWindow* window, const WindowInfo& window err = native_window_set_buffers_data_space(window, windowInfo.dataspace); if (err != 0) { ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffers_data_space(%d) " - "failed: %s (%d)", windowInfo.dataspace, strerror(-err), err); + "failed: %s (%d)", + windowInfo.dataspace, strerror(-err), err); return false; } @@ -345,7 +340,8 @@ bool VulkanSurface::UpdateWindow(ANativeWindow* window, const WindowInfo& window err = native_window_set_buffers_dimensions(window, size.width(), size.height()); if (err != 0) { ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffers_dimensions(%d,%d) " - "failed: %s (%d)", size.width(), size.height(), strerror(-err), err); + "failed: %s (%d)", + size.width(), size.height(), strerror(-err), err); return false; } @@ -358,7 +354,8 @@ bool VulkanSurface::UpdateWindow(ANativeWindow* window, const WindowInfo& window err = native_window_set_buffers_transform(window, InvertTransform(windowInfo.transform)); if (err != 0) { ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffers_transform(%d) " - "failed: %s (%d)", windowInfo.transform, strerror(-err), err); + "failed: %s (%d)", + windowInfo.transform, strerror(-err), err); return false; } @@ -367,7 +364,8 @@ bool VulkanSurface::UpdateWindow(ANativeWindow* window, const WindowInfo& window err = native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_FREEZE); if (err != 0) { ALOGE("VulkanSurface::UpdateWindow() native_window_set_scaling_mode(SCALE_TO_WINDOW) " - "failed: %s (%d)", strerror(-err), err); + "failed: %s (%d)", + strerror(-err), err); return false; } @@ -389,12 +387,12 @@ bool VulkanSurface::UpdateWindow(ANativeWindow* window, const WindowInfo& window } VulkanSurface::VulkanSurface(ANativeWindow* window, const WindowInfo& windowInfo, - SkISize minWindowSize, SkISize maxWindowSize, GrContext* grContext) + SkISize minWindowSize, SkISize maxWindowSize, GrContext* grContext) : mNativeWindow(window) , mWindowInfo(windowInfo) , mGrContext(grContext) , mMinWindowSize(minWindowSize) - , mMaxWindowSize(maxWindowSize) { } + , mMaxWindowSize(maxWindowSize) {} VulkanSurface::~VulkanSurface() { releaseBuffers(); @@ -437,8 +435,7 @@ VulkanSurface::NativeBufferInfo* VulkanSurface::dequeueNativeBuffer() { // value at the end of the function if everything dequeued correctly. mCurrentBufferInfo = nullptr; - - //check if the native window has been resized or rotated and update accordingly + // check if the native window has been resized or rotated and update accordingly SkISize newSize = SkISize::MakeEmpty(); int transformHint = 0; mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_WIDTH, &newSize.fWidth); @@ -458,8 +455,8 @@ VulkanSurface::NativeBufferInfo* VulkanSurface::dequeueNativeBuffer() { newWindowInfo.actualSize.height()); if (err != 0) { ALOGE("native_window_set_buffers_dimensions(%d,%d) failed: %s (%d)", - newWindowInfo.actualSize.width(), - newWindowInfo.actualSize.height(), strerror(-err), err); + newWindowInfo.actualSize.width(), newWindowInfo.actualSize.height(), + strerror(-err), err); return nullptr; } // reset the NativeBufferInfo (including SkSurface) associated with the old buffers. The @@ -470,7 +467,7 @@ VulkanSurface::NativeBufferInfo* VulkanSurface::dequeueNativeBuffer() { if (newWindowInfo.transform != mWindowInfo.transform) { err = native_window_set_buffers_transform(mNativeWindow.get(), - InvertTransform(newWindowInfo.transform)); + InvertTransform(newWindowInfo.transform)); if (err != 0) { ALOGE("native_window_set_buffers_transform(%d) failed: %s (%d)", newWindowInfo.transform, strerror(-err), err); @@ -513,11 +510,9 @@ VulkanSurface::NativeBufferInfo* VulkanSurface::dequeueNativeBuffer() { VulkanSurface::NativeBufferInfo* bufferInfo = &mNativeBuffers[idx]; if (bufferInfo->skSurface.get() == nullptr) { - bufferInfo->skSurface = - SkSurface::MakeFromAHardwareBuffer(mGrContext, - ANativeWindowBuffer_getHardwareBuffer(bufferInfo->buffer.get()), - kTopLeft_GrSurfaceOrigin, DataSpaceToColorSpace(mWindowInfo.dataspace), - nullptr); + bufferInfo->skSurface = SkSurface::MakeFromAHardwareBuffer( + mGrContext, ANativeWindowBuffer_getHardwareBuffer(bufferInfo->buffer.get()), + kTopLeft_GrSurfaceOrigin, DataSpaceToColorSpace(mWindowInfo.dataspace), nullptr); if (bufferInfo->skSurface.get() == nullptr) { ALOGE("SkSurface::MakeFromAHardwareBuffer failed"); mNativeWindow->cancelBuffer(mNativeWindow.get(), buffer, fence_fd); diff --git a/libs/hwui/renderthread/VulkanSurface.h b/libs/hwui/renderthread/VulkanSurface.h index 305483fce2d59..b7af596ae7628 100644 --- a/libs/hwui/renderthread/VulkanSurface.h +++ b/libs/hwui/renderthread/VulkanSurface.h @@ -19,8 +19,8 @@ #include #include -#include #include +#include #include "IRenderPipeline.h" @@ -34,12 +34,9 @@ class VulkanManager; class VulkanSurface { public: - static VulkanSurface* Create(ANativeWindow* window, - ColorMode colorMode, - SkColorType colorType, - sk_sp colorSpace, - GrContext* grContext, - const VulkanManager& vkManager); + static VulkanSurface* Create(ANativeWindow* window, ColorMode colorMode, SkColorType colorType, + sk_sp colorSpace, GrContext* grContext, + const VulkanManager& vkManager, uint32_t extraBuffers); ~VulkanSurface(); sk_sp getCurrentSkSurface() { @@ -104,15 +101,10 @@ private: SkMatrix preTransform; }; - VulkanSurface(ANativeWindow* window, - const WindowInfo& windowInfo, - SkISize minWindowSize, - SkISize maxWindowSize, - GrContext* grContext); - static bool UpdateWindow(ANativeWindow* window, - const WindowInfo& windowInfo); - static void ComputeWindowSizeAndTransform(WindowInfo* windowInfo, - const SkISize& minSize, + VulkanSurface(ANativeWindow* window, const WindowInfo& windowInfo, SkISize minWindowSize, + SkISize maxWindowSize, GrContext* grContext); + static bool UpdateWindow(ANativeWindow* window, const WindowInfo& windowInfo); + static void ComputeWindowSizeAndTransform(WindowInfo* windowInfo, const SkISize& minSize, const SkISize& maxSize); void releaseBuffers(); diff --git a/libs/hwui/tests/unit/SkiaPipelineTests.cpp b/libs/hwui/tests/unit/SkiaPipelineTests.cpp index e86cf42fee4d2..a671bdada09af 100644 --- a/libs/hwui/tests/unit/SkiaPipelineTests.cpp +++ b/libs/hwui/tests/unit/SkiaPipelineTests.cpp @@ -31,6 +31,9 @@ #include "renderthread/CanvasContext.h" #include "tests/common/TestUtils.h" +#include +#include + using namespace android; using namespace android::uirenderer; using namespace android::uirenderer::renderthread; @@ -421,10 +424,20 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, clip_replace) { EXPECT_EQ(1, surface->canvas()->mDrawCounter); } +static sp createDummySurface() { + sp producer; + sp consumer; + BufferQueue::createBufferQueue(&producer, &consumer); + producer->setMaxDequeuedBufferCount(1); + producer->setAsyncMode(true); + return new Surface(producer); +} + RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, context_lost) { + auto surface = createDummySurface(); auto pipeline = std::make_unique(renderThread); EXPECT_FALSE(pipeline->isSurfaceReady()); - EXPECT_TRUE(pipeline->setSurface((Surface*)0x01, SwapBehavior::kSwap_default, ColorMode::SRGB)); + EXPECT_TRUE(pipeline->setSurface(surface.get(), SwapBehavior::kSwap_default, ColorMode::SRGB, 0)); EXPECT_TRUE(pipeline->isSurfaceReady()); renderThread.destroyRenderingContext(); EXPECT_FALSE(pipeline->isSurfaceReady());