diff options
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/androidfw/ApkAssets.cpp | 15 | ||||
| -rw-r--r-- | libs/androidfw/include/androidfw/ApkAssets.h | 5 | ||||
| -rw-r--r-- | libs/hwui/Readback.cpp | 2 | ||||
| -rw-r--r-- | libs/hwui/pipeline/skia/VkFunctorDrawable.cpp | 27 | ||||
| -rw-r--r-- | libs/hwui/renderthread/RenderProxy.cpp | 2 | ||||
| -rw-r--r-- | libs/hwui/renderthread/VulkanSurface.cpp | 19 | ||||
| -rw-r--r-- | libs/hwui/renderthread/VulkanSurface.h | 12 |
7 files changed, 67 insertions, 15 deletions
diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp index 66a547723b2f..7b7599ff74ec 100644 --- a/libs/androidfw/ApkAssets.cpp +++ b/libs/androidfw/ApkAssets.cpp @@ -29,6 +29,7 @@ #include "androidfw/Asset.h" #include "androidfw/Idmap.h" +#include "androidfw/misc.h" #include "androidfw/ResourceTypes.h" #include "androidfw/Util.h" @@ -39,8 +40,10 @@ using base::unique_fd; static const std::string kResourcesArsc("resources.arsc"); -ApkAssets::ApkAssets(ZipArchiveHandle unmanaged_handle, const std::string& path) - : zip_handle_(unmanaged_handle, ::CloseArchive), path_(path) { +ApkAssets::ApkAssets(ZipArchiveHandle unmanaged_handle, + const std::string& path, + time_t last_mod_time) + : zip_handle_(unmanaged_handle, ::CloseArchive), path_(path), last_mod_time_(last_mod_time) { } std::unique_ptr<const ApkAssets> ApkAssets::Load(const std::string& path, bool system) { @@ -116,8 +119,10 @@ std::unique_ptr<const ApkAssets> ApkAssets::LoadImpl( return {}; } + time_t last_mod_time = getFileModDate(path.c_str()); + // Wrap the handle in a unique_ptr so it gets automatically closed. - std::unique_ptr<ApkAssets> loaded_apk(new ApkAssets(unmanaged_handle, path)); + std::unique_ptr<ApkAssets> loaded_apk(new ApkAssets(unmanaged_handle, path, last_mod_time)); // Find the resource table. ::ZipString entry_name(kResourcesArsc.c_str()); @@ -248,4 +253,8 @@ bool ApkAssets::ForEachFile(const std::string& root_path, return result == -1; } +bool ApkAssets::IsUpToDate() const { + return last_mod_time_ == getFileModDate(path_.c_str()); +} + } // namespace android diff --git a/libs/androidfw/include/androidfw/ApkAssets.h b/libs/androidfw/include/androidfw/ApkAssets.h index 35bbb5804df4..49fc82bff11e 100644 --- a/libs/androidfw/include/androidfw/ApkAssets.h +++ b/libs/androidfw/include/androidfw/ApkAssets.h @@ -84,6 +84,8 @@ class ApkAssets { return idmap_asset_.get() != nullptr; } + bool IsUpToDate() const; + private: DISALLOW_COPY_AND_ASSIGN(ApkAssets); @@ -95,12 +97,13 @@ class ApkAssets { // Creates an Asset from any file on the file system. static std::unique_ptr<Asset> CreateAssetFromFile(const std::string& path); - ApkAssets(ZipArchiveHandle unmanaged_handle, const std::string& path); + ApkAssets(ZipArchiveHandle unmanaged_handle, const std::string& path, time_t last_mod_time); using ZipArchivePtr = std::unique_ptr<ZipArchive, void(*)(ZipArchiveHandle)>; ZipArchivePtr zip_handle_; const std::string path_; + time_t last_mod_time_; std::unique_ptr<Asset> resources_asset_; std::unique_ptr<Asset> idmap_asset_; std::unique_ptr<const LoadedArsc> loaded_arsc_; diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp index fb60a966c48f..89a9b997af97 100644 --- a/libs/hwui/Readback.cpp +++ b/libs/hwui/Readback.cpp @@ -84,6 +84,7 @@ CopyResult Readback::copyHWBitmapInto(Bitmap* hwBitmap, SkBitmap* bitmap) { } CopyResult Readback::copyLayerInto(DeferredLayerUpdater* deferredLayer, SkBitmap* bitmap) { + ATRACE_CALL(); if (!mRenderThread.getGrContext()) { return CopyResult::UnknownError; } @@ -104,6 +105,7 @@ CopyResult Readback::copyLayerInto(DeferredLayerUpdater* deferredLayer, SkBitmap CopyResult Readback::copyImageInto(const sk_sp<SkImage>& image, Matrix4& texTransform, const Rect& srcRect, SkBitmap* bitmap) { + ATRACE_CALL(); if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) { mRenderThread.requireGlContext(); } else { diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp index ceab407cb939..1b9e53b21adb 100644 --- a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp +++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp @@ -19,6 +19,7 @@ #include "renderthread/VulkanManager.h" #include "renderthread/RenderThread.h" +#include <SkAndroidFrameworkUtils.h> #include <GrBackendDrawableInfo.h> #include <SkImage.h> #include <utils/Color.h> @@ -89,9 +90,29 @@ void VkFunctorDrawHandler::draw(const GrBackendDrawableInfo& info) { VkFunctorDrawable::~VkFunctorDrawable() { } -void VkFunctorDrawable::onDraw(SkCanvas* /*canvas*/) { - LOG_ALWAYS_FATAL("VkFunctorDrawable::onDraw() should never be called."); - // Instead of calling onDraw(), the call should come from onSnapGpuDrawHandler. +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->getGrContext() == 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( diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index 1bcb819509af..16240b4e177b 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -162,6 +162,7 @@ void RenderProxy::buildLayer(RenderNode* node) { } bool RenderProxy::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap& bitmap) { + ATRACE_NAME("TextureView#getBitmap"); auto& thread = RenderThread::getInstance(); return thread.queue().runSync([&]() -> bool { return thread.readback().copyLayerInto(layer, &bitmap) == CopyResult::Success; @@ -347,6 +348,7 @@ void RenderProxy::prepareToDraw(Bitmap& bitmap) { } int RenderProxy::copyHWBitmapInto(Bitmap* hwBitmap, SkBitmap* bitmap) { + ATRACE_NAME("HardwareBitmap readback"); RenderThread& thread = RenderThread::getInstance(); if (gettid() == thread.getTid()) { // TODO: fix everything that hits this. We should never be triggering a readback ourselves. diff --git a/libs/hwui/renderthread/VulkanSurface.cpp b/libs/hwui/renderthread/VulkanSurface.cpp index 1708d3c0e093..3fed6b09ede2 100644 --- a/libs/hwui/renderthread/VulkanSurface.cpp +++ b/libs/hwui/renderthread/VulkanSurface.cpp @@ -222,7 +222,17 @@ VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode, const SkISize maxSize = SkISize::Make(caps.maxImageExtent.width, caps.maxImageExtent.height); ComputeWindowSizeAndTransform(&windowInfo, minSize, maxSize); - windowInfo.bufferCount = std::max<uint32_t>(VulkanSurface::sMaxBufferCount, caps.minImageCount); + 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 nullptr; + } + auto min_undequeued_buffers = static_cast<uint32_t>(query_value); + + windowInfo.bufferCount = min_undequeued_buffers + + std::max(VulkanSurface::sTargetBufferCount, caps.minImageCount); if (caps.maxImageCount > 0 && windowInfo.bufferCount > caps.maxImageCount) { // Application must settle for fewer images than desired: windowInfo.bufferCount = caps.maxImageCount; @@ -357,10 +367,9 @@ bool VulkanSurface::UpdateWindow(ANativeWindow* window, const WindowInfo& window return false; } - // Lower layer insists that we have at least two buffers. - err = native_window_set_buffer_count(window, std::max(2, windowInfo.bufferCount)); + err = native_window_set_buffer_count(window, windowInfo.bufferCount); if (err != 0) { - ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffer_count(%d) failed: %s (%d)", + ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffer_count(%zu) failed: %s (%d)", windowInfo.bufferCount, strerror(-err), err); return false; } @@ -392,7 +401,7 @@ VulkanSurface::~VulkanSurface() { } void VulkanSurface::releaseBuffers() { - for (uint32_t i = 0; i < VulkanSurface::sMaxBufferCount; i++) { + for (uint32_t i = 0; i < mWindowInfo.bufferCount; i++) { VulkanSurface::NativeBufferInfo& bufferInfo = mNativeBuffers[i]; if (bufferInfo.buffer.get() != nullptr && bufferInfo.dequeued) { diff --git a/libs/hwui/renderthread/VulkanSurface.h b/libs/hwui/renderthread/VulkanSurface.h index 418d40f8c056..305483fce2d5 100644 --- a/libs/hwui/renderthread/VulkanSurface.h +++ b/libs/hwui/renderthread/VulkanSurface.h @@ -83,14 +83,19 @@ private: * as private to this class. * */ - static constexpr int sMaxBufferCount = 3; + + // How many buffers we want to be able to use ourselves. We want 1 in active rendering with + // 1 more queued, so 2. This will be added to NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, which is + // how many buffers the consumer needs (eg, 1 for SurfaceFlinger), getting to a typically + // triple-buffered queue as a result. + static constexpr uint32_t sTargetBufferCount = 2; struct WindowInfo { SkISize size; PixelFormat pixelFormat; android_dataspace dataspace; int transform; - int bufferCount; + size_t bufferCount; uint64_t windowUsageFlags; // size of the ANativeWindow if the inverse of transform requires us to swap width/height @@ -111,7 +116,8 @@ private: const SkISize& maxSize); void releaseBuffers(); - NativeBufferInfo mNativeBuffers[VulkanSurface::sMaxBufferCount]; + // TODO: Just use a vector? + NativeBufferInfo mNativeBuffers[android::BufferQueueDefs::NUM_BUFFER_SLOTS]; sp<ANativeWindow> mNativeWindow; WindowInfo mWindowInfo; |