Merge "Avoid excessive KGSL maps" into rvc-dev am: acf8443e9a am: 906a94baec am: d292bcc672

Change-Id: I6392d7d10ad2727ca290e0acfd9f56f2b362a277
This commit is contained in:
John Reck
2020-05-10 05:43:03 +00:00
committed by Automerger Merge Worker
9 changed files with 79 additions and 39 deletions

View File

@@ -157,21 +157,7 @@ void SkiaOpenGLPipeline::onStop() {
} }
} }
static void setBufferCount(ANativeWindow* window, uint32_t extraBuffers) { bool SkiaOpenGLPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior) {
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<uint32_t>(query_value);
int bufferCount = min_undequeued_buffers + 2 + extraBuffers;
native_window_set_buffer_count(window, bufferCount);
}
bool SkiaOpenGLPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior,
uint32_t extraBuffers) {
if (mEglSurface != EGL_NO_SURFACE) { if (mEglSurface != EGL_NO_SURFACE) {
mEglManager.destroySurface(mEglSurface); mEglManager.destroySurface(mEglSurface);
mEglSurface = EGL_NO_SURFACE; mEglSurface = EGL_NO_SURFACE;
@@ -189,7 +175,6 @@ bool SkiaOpenGLPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBeh
if (mEglSurface != EGL_NO_SURFACE) { if (mEglSurface != EGL_NO_SURFACE) {
const bool preserveBuffer = (swapBehavior != SwapBehavior::kSwap_discardBuffer); const bool preserveBuffer = (swapBehavior != SwapBehavior::kSwap_discardBuffer);
mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer); mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer);
setBufferCount(surface, extraBuffers);
return true; return true;
} }

View File

@@ -45,8 +45,7 @@ public:
bool swapBuffers(const renderthread::Frame& frame, bool drew, const SkRect& screenDirty, bool swapBuffers(const renderthread::Frame& frame, bool drew, const SkRect& screenDirty,
FrameInfo* currentFrameInfo, bool* requireSwap) override; FrameInfo* currentFrameInfo, bool* requireSwap) override;
DeferredLayerUpdater* createTextureLayer() override; DeferredLayerUpdater* createTextureLayer() override;
bool setSurface(ANativeWindow* surface, renderthread::SwapBehavior swapBehavior, bool setSurface(ANativeWindow* surface, renderthread::SwapBehavior swapBehavior) override;
uint32_t extraBuffers) override;
void onStop() override; void onStop() override;
bool isSurfaceReady() override; bool isSurfaceReady() override;
bool isContextReady() override; bool isContextReady() override;

View File

@@ -116,8 +116,7 @@ DeferredLayerUpdater* SkiaVulkanPipeline::createTextureLayer() {
void SkiaVulkanPipeline::onStop() {} void SkiaVulkanPipeline::onStop() {}
bool SkiaVulkanPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior, bool SkiaVulkanPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior) {
uint32_t extraBuffers) {
if (mVkSurface) { if (mVkSurface) {
mVkManager.destroySurface(mVkSurface); mVkManager.destroySurface(mVkSurface);
mVkSurface = nullptr; mVkSurface = nullptr;
@@ -127,7 +126,7 @@ bool SkiaVulkanPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBeh
mRenderThread.requireVkContext(); mRenderThread.requireVkContext();
mVkSurface = mVkSurface =
mVkManager.createSurface(surface, mColorMode, mSurfaceColorSpace, mSurfaceColorType, mVkManager.createSurface(surface, mColorMode, mSurfaceColorSpace, mSurfaceColorType,
mRenderThread.getGrContext(), extraBuffers); mRenderThread.getGrContext(), 0);
} }
return mVkSurface != nullptr; return mVkSurface != nullptr;

View File

@@ -42,8 +42,7 @@ public:
bool swapBuffers(const renderthread::Frame& frame, bool drew, const SkRect& screenDirty, bool swapBuffers(const renderthread::Frame& frame, bool drew, const SkRect& screenDirty,
FrameInfo* currentFrameInfo, bool* requireSwap) override; FrameInfo* currentFrameInfo, bool* requireSwap) override;
DeferredLayerUpdater* createTextureLayer() override; DeferredLayerUpdater* createTextureLayer() override;
bool setSurface(ANativeWindow* surface, renderthread::SwapBehavior swapBehavior, bool setSurface(ANativeWindow* surface, renderthread::SwapBehavior swapBehavior) override;
uint32_t extraBuffers) override;
void onStop() override; void onStop() override;
bool isSurfaceReady() override; bool isSurfaceReady() override;
bool isContextReady() override; bool isContextReady() override;

View File

@@ -139,20 +139,22 @@ void CanvasContext::destroy() {
mAnimationContext->destroy(); mAnimationContext->destroy();
} }
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<uint32_t>(query_value);
int bufferCount = min_undequeued_buffers + 2 + extraBuffers;
native_window_set_buffer_count(window, bufferCount);
}
void CanvasContext::setSurface(ANativeWindow* window, bool enableTimeout) { void CanvasContext::setSurface(ANativeWindow* window, bool enableTimeout) {
ATRACE_CALL(); ATRACE_CALL();
if (window) {
mNativeSurface = std::make_unique<ReliableSurface>(window);
mNativeSurface->init();
if (enableTimeout) {
// TODO: Fix error handling & re-shorten timeout
ANativeWindow_setDequeueTimeout(window, 4000_ms);
}
} else {
mNativeSurface = nullptr;
}
if (mRenderAheadDepth == 0 && DeviceInfo::get()->getMaxRefreshRate() > 66.6f) { if (mRenderAheadDepth == 0 && DeviceInfo::get()->getMaxRefreshRate() > 66.6f) {
mFixedRenderAhead = false; mFixedRenderAhead = false;
mRenderAheadCapacity = 1; mRenderAheadCapacity = 1;
@@ -161,9 +163,24 @@ void CanvasContext::setSurface(ANativeWindow* window, bool enableTimeout) {
mRenderAheadCapacity = mRenderAheadDepth; mRenderAheadCapacity = mRenderAheadDepth;
} }
if (window) {
mNativeSurface = std::make_unique<ReliableSurface>(window);
mNativeSurface->init();
if (enableTimeout) {
// TODO: Fix error handling & re-shorten timeout
ANativeWindow_setDequeueTimeout(window, 4000_ms);
}
mNativeSurface->setExtraBufferCount(mRenderAheadCapacity);
} else {
mNativeSurface = nullptr;
}
bool hasSurface = mRenderPipeline->setSurface( bool hasSurface = mRenderPipeline->setSurface(
mNativeSurface ? mNativeSurface->getNativeWindow() : nullptr, mSwapBehavior, mNativeSurface ? mNativeSurface->getNativeWindow() : nullptr, mSwapBehavior);
mRenderAheadCapacity);
if (mNativeSurface && !mNativeSurface->didSetExtraBuffers()) {
setBufferCount(mNativeSurface->getNativeWindow(), mRenderAheadCapacity);
}
mFrameNumber = -1; mFrameNumber = -1;

View File

@@ -66,8 +66,7 @@ public:
virtual bool swapBuffers(const Frame& frame, bool drew, const SkRect& screenDirty, virtual bool swapBuffers(const Frame& frame, bool drew, const SkRect& screenDirty,
FrameInfo* currentFrameInfo, bool* requireSwap) = 0; FrameInfo* currentFrameInfo, bool* requireSwap) = 0;
virtual DeferredLayerUpdater* createTextureLayer() = 0; virtual DeferredLayerUpdater* createTextureLayer() = 0;
virtual bool setSurface(ANativeWindow* window, SwapBehavior swapBehavior, virtual bool setSurface(ANativeWindow* window, SwapBehavior swapBehavior) = 0;
uint32_t extraBuffers) = 0;
virtual void onStop() = 0; virtual void onStop() = 0;
virtual bool isSurfaceReady() = 0; virtual bool isSurfaceReady() = 0;
virtual bool isContextReady() = 0; virtual bool isContextReady() = 0;

View File

@@ -19,6 +19,7 @@
#include <log/log_main.h> #include <log/log_main.h>
#include <private/android/AHardwareBufferHelpers.h> #include <private/android/AHardwareBufferHelpers.h>
// TODO: this should be including apex instead. // TODO: this should be including apex instead.
#include <system/window.h>
#include <vndk/window.h> #include <vndk/window.h>
namespace android::uirenderer::renderthread { namespace android::uirenderer::renderthread {
@@ -44,6 +45,7 @@ ReliableSurface::~ReliableSurface() {
ANativeWindow_setDequeueBufferInterceptor(mWindow, nullptr, nullptr); ANativeWindow_setDequeueBufferInterceptor(mWindow, nullptr, nullptr);
ANativeWindow_setQueueBufferInterceptor(mWindow, nullptr, nullptr); ANativeWindow_setQueueBufferInterceptor(mWindow, nullptr, nullptr);
ANativeWindow_setPerformInterceptor(mWindow, nullptr, nullptr); ANativeWindow_setPerformInterceptor(mWindow, nullptr, nullptr);
ANativeWindow_setQueryInterceptor(mWindow, nullptr, nullptr);
ANativeWindow_release(mWindow); ANativeWindow_release(mWindow);
} }
@@ -63,6 +65,10 @@ void ReliableSurface::init() {
result = ANativeWindow_setPerformInterceptor(mWindow, hook_perform, this); result = ANativeWindow_setPerformInterceptor(mWindow, hook_perform, this);
LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set perform interceptor: error = %d", LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set perform interceptor: error = %d",
result); result);
result = ANativeWindow_setQueryInterceptor(mWindow, hook_query, this);
LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set query interceptor: error = %d",
result);
} }
int ReliableSurface::reserveNext() { int ReliableSurface::reserveNext() {
@@ -249,9 +255,29 @@ int ReliableSurface::hook_perform(ANativeWindow* window, ANativeWindow_performFn
case ANATIVEWINDOW_PERFORM_SET_BUFFERS_FORMAT: case ANATIVEWINDOW_PERFORM_SET_BUFFERS_FORMAT:
rs->mFormat = static_cast<AHardwareBuffer_Format>(va_arg(args, int32_t)); rs->mFormat = static_cast<AHardwareBuffer_Format>(va_arg(args, int32_t));
break; break;
case NATIVE_WINDOW_SET_BUFFER_COUNT:
size_t bufferCount = va_arg(args, size_t);
if (bufferCount >= rs->mExpectedBufferCount) {
rs->mDidSetExtraBuffers = true;
} else {
ALOGD("HOOK FAILED! Expected %zd got = %zd", rs->mExpectedBufferCount, bufferCount);
}
break;
} }
} }
return result; return result;
} }
int ReliableSurface::hook_query(const ANativeWindow *window, ANativeWindow_queryFn query,
void *data, int what, int *value) {
ReliableSurface* rs = reinterpret_cast<ReliableSurface*>(data);
int result = query(window, what, value);
if (what == ANATIVEWINDOW_QUERY_MIN_UNDEQUEUED_BUFFERS && result == OK) {
std::lock_guard _lock{rs->mMutex};
*value += rs->mExtraBuffers;
rs->mExpectedBufferCount = *value + 2;
}
return result;
}
}; // namespace android::uirenderer::renderthread }; // namespace android::uirenderer::renderthread

View File

@@ -17,6 +17,7 @@
#pragma once #pragma once
#include <android-base/unique_fd.h> #include <android-base/unique_fd.h>
#include <system/window.h>
#include <apex/window.h> #include <apex/window.h>
#include <utils/Errors.h> #include <utils/Errors.h>
#include <utils/Macros.h> #include <utils/Macros.h>
@@ -49,6 +50,16 @@ public:
return ret; return ret;
} }
void setExtraBufferCount(size_t extraBuffers) {
std::lock_guard _lock{mMutex};
mExtraBuffers = extraBuffers;
}
bool didSetExtraBuffers() const {
std::lock_guard _lock{mMutex};
return mDidSetExtraBuffers;
}
private: private:
ANativeWindow* mWindow; ANativeWindow* mWindow;
@@ -62,6 +73,9 @@ private:
base::unique_fd mReservedFenceFd; base::unique_fd mReservedFenceFd;
bool mHasDequeuedBuffer = false; bool mHasDequeuedBuffer = false;
int mBufferQueueState = OK; int mBufferQueueState = OK;
size_t mExtraBuffers = 0;
size_t mExpectedBufferCount = 0;
bool mDidSetExtraBuffers = false;
bool isFallbackBuffer(const ANativeWindowBuffer* windowBuffer) const; bool isFallbackBuffer(const ANativeWindowBuffer* windowBuffer) const;
ANativeWindowBuffer* acquireFallbackBuffer(int error); ANativeWindowBuffer* acquireFallbackBuffer(int error);
@@ -81,6 +95,8 @@ private:
static int hook_perform(ANativeWindow* window, ANativeWindow_performFn perform, void* data, static int hook_perform(ANativeWindow* window, ANativeWindow_performFn perform, void* data,
int operation, va_list args); int operation, va_list args);
static int hook_query(const ANativeWindow* window, ANativeWindow_queryFn query, void* data,
int what, int* value);
}; };
}; // namespace android::uirenderer::renderthread }; // namespace android::uirenderer::renderthread

View File

@@ -398,7 +398,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, context_lost) {
auto surface = context.surface(); auto surface = context.surface();
auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread); auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
EXPECT_FALSE(pipeline->isSurfaceReady()); EXPECT_FALSE(pipeline->isSurfaceReady());
EXPECT_TRUE(pipeline->setSurface(surface.get(), SwapBehavior::kSwap_default, 0)); EXPECT_TRUE(pipeline->setSurface(surface.get(), SwapBehavior::kSwap_default));
EXPECT_TRUE(pipeline->isSurfaceReady()); EXPECT_TRUE(pipeline->isSurfaceReady());
renderThread.destroyRenderingContext(); renderThread.destroyRenderingContext();
EXPECT_FALSE(pipeline->isSurfaceReady()); EXPECT_FALSE(pipeline->isSurfaceReady());