diff options
author | John Reck <jreck@google.com> | 2016-08-02 02:57:27 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2016-08-02 02:57:27 +0000 |
commit | 8b9a1fa0848df557d5c718f3ef1230e6a82a320a (patch) | |
tree | 9635e321ff856b5c85af23b33fe4ae3b5bdeece4 /libs/hwui/renderthread/RenderProxy.cpp | |
parent | d56560eb7c91ddc506e0799b54968c27f362558b (diff) | |
parent | 897b9effb7f84c241bc68686c09324987c1dba37 (diff) |
Eliminate recents upload jank am: 4387190d8e am: 021a952150
am: 897b9effb7
Change-Id: Iab2f01b5b3a9be6946e36169209c281a3320ed14
Diffstat (limited to 'libs/hwui/renderthread/RenderProxy.cpp')
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.cpp | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index ad1af4043d10..d6eea877de0c 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -21,9 +21,11 @@ #include "Readback.h" #include "Rect.h" #include "renderthread/CanvasContext.h" +#include "renderthread/EglManager.h" #include "renderthread/RenderTask.h" #include "renderthread/RenderThread.h" #include "utils/Macros.h" +#include "utils/TimeUtils.h" namespace android { namespace uirenderer { @@ -43,6 +45,8 @@ namespace renderthread { typedef struct { \ a1; a2; a3; a4; a5; a6; a7; a8; \ } ARGS(name); \ + static_assert(std::is_trivially_destructible<ARGS(name)>::value, \ + "Error, ARGS must be trivially destructible!"); \ static void* Bridge_ ## name(ARGS(name)* args) #define SETUP_TASK(method) \ @@ -628,6 +632,41 @@ int RenderProxy::copySurfaceInto(sp<Surface>& surface, SkBitmap* bitmap) { reinterpret_cast<intptr_t>( staticPostAndWait(task) )); } +CREATE_BRIDGE2(prepareToDraw, RenderThread* thread, SkBitmap* bitmap) { + if (Caches::hasInstance() && args->thread->eglManager().hasEglContext()) { + ATRACE_NAME("Bitmap#prepareToDraw task"); + Caches::getInstance().textureCache.prefetch(args->bitmap); + } + delete args->bitmap; + args->bitmap = nullptr; + return nullptr; +} + +void RenderProxy::prepareToDraw(const SkBitmap& bitmap) { + // If we haven't spun up a hardware accelerated window yet, there's no + // point in precaching these bitmaps as it can't impact jank. + // We also don't know if we even will spin up a hardware-accelerated + // window or not. + if (!RenderThread::hasInstance()) return; + RenderThread* renderThread = &RenderThread::getInstance(); + SETUP_TASK(prepareToDraw); + args->thread = renderThread; + args->bitmap = new SkBitmap(bitmap); + nsecs_t lastVsync = renderThread->timeLord().latestVsync(); + nsecs_t estimatedNextVsync = lastVsync + renderThread->timeLord().frameIntervalNanos(); + nsecs_t timeToNextVsync = estimatedNextVsync - systemTime(CLOCK_MONOTONIC); + // We expect the UI thread to take 4ms and for RT to be active from VSYNC+4ms to + // VSYNC+12ms or so, so aim for the gap during which RT is expected to + // be idle + // TODO: Make this concept a first-class supported thing? RT could use + // knowledge of pending draws to better schedule this task + if (timeToNextVsync > -6_ms && timeToNextVsync < 1_ms) { + renderThread->queueAt(task, estimatedNextVsync + 8_ms); + } else { + renderThread->queue(task); + } +} + void RenderProxy::post(RenderTask* task) { mRenderThread.queue(task); } |