summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/androidfw/ApkAssets.cpp15
-rw-r--r--libs/androidfw/include/androidfw/ApkAssets.h5
-rw-r--r--libs/hwui/Readback.cpp2
-rw-r--r--libs/hwui/pipeline/skia/VkFunctorDrawable.cpp27
-rw-r--r--libs/hwui/renderthread/RenderProxy.cpp2
-rw-r--r--libs/hwui/renderthread/VulkanSurface.cpp19
-rw-r--r--libs/hwui/renderthread/VulkanSurface.h12
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;