Move OpenGL specific details behind renderPipeline interface.
Test: new and existing unit tests still pass.
Change-Id: I6164f30f45ebe450788ed8d949eca5af9a44e585
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 5069a9a..a9bd75c 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -266,6 +266,7 @@
tests/unit/BakedOpDispatcherTests.cpp \
tests/unit/BakedOpRendererTests.cpp \
tests/unit/BakedOpStateTests.cpp \
+ tests/unit/CanvasContextTests.cpp \
tests/unit/CanvasStateTests.cpp \
tests/unit/ClipAreaTests.cpp \
tests/unit/DamageAccumulatorTests.cpp \
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index fe0f56a..8ed8893 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -97,6 +97,31 @@
}
}
+void CanvasContext::invokeFunctor(const RenderThread& thread, Functor* functor) {
+ ATRACE_CALL();
+ auto renderType = Properties::getRenderPipelineType();
+ switch (renderType) {
+ case RenderPipelineType::OpenGL:
+ OpenGLPipeline::invokeFunctor(thread, functor);
+ break;
+ default:
+ LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType);
+ break;
+ }
+}
+
+void CanvasContext::prepareToDraw(const RenderThread& thread, Bitmap* bitmap) {
+ auto renderType = Properties::getRenderPipelineType();
+ switch (renderType) {
+ case RenderPipelineType::OpenGL:
+ OpenGLPipeline::prepareToDraw(thread, bitmap);
+ break;
+ default:
+ LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType);
+ break;
+ }
+}
+
CanvasContext::CanvasContext(RenderThread& thread, bool translucent,
RenderNode* rootRenderNode, IContextFactory* contextFactory,
std::unique_ptr<IRenderPipeline> renderPipeline)
@@ -425,8 +450,11 @@
GpuMemoryTracker::onFrameCompleted();
#ifdef BUGREPORT_FONT_CACHE_USAGE
- Caches& caches = Caches::getInstance();
- caches.fontRenderer.getFontRenderer().historyTracker().frameCompleted();
+ auto renderType = Properties::getRenderPipelineType();
+ if (RenderPipelineType::OpenGL == renderType) {
+ Caches& caches = Caches::getInstance();
+ caches.fontRenderer.getFontRenderer().historyTracker().frameCompleted();
+ }
#endif
}
@@ -456,16 +484,6 @@
}
}
-void CanvasContext::invokeFunctor(RenderThread& thread, Functor* functor) {
- ATRACE_CALL();
- DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext;
- if (thread.eglManager().hasEglContext()) {
- mode = DrawGlInfo::kModeProcess;
- }
-
- thread.renderState().invokeFunctor(functor, mode, nullptr);
-}
-
void CanvasContext::markLayerInUse(RenderNode* node) {
if (mPrefetchedLayers.erase(node)) {
node->decStrong(nullptr);
@@ -520,10 +538,6 @@
for (const sp<RenderNode>& node : mRenderNodes) {
node->destroyHardwareResources(observer);
}
- Caches& caches = Caches::getInstance();
- // Make sure to release all the textures we were owning as there won't
- // be another draw
- caches.textureCache.resetMarkInUse(this);
mRenderPipeline->onDestroyHardwareResources();
}
}
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 125f109..b61eef2 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -85,6 +85,10 @@
*/
static void destroyLayer(RenderNode* node);
+ static void invokeFunctor(const RenderThread& thread, Functor* functor);
+
+ static void prepareToDraw(const RenderThread& thread, Bitmap* bitmap);
+
/*
* If Properties::isSkiaEnabled() is true then this will return the Skia
* grContext associated with the current RenderPipeline.
@@ -121,8 +125,6 @@
void destroyHardwareResources(TreeObserver* observer);
static void trimMemory(RenderThread& thread, int level);
- static void invokeFunctor(RenderThread& thread, Functor* functor);
-
DeferredLayerUpdater* createTextureLayer();
void stopDrawing();
diff --git a/libs/hwui/renderthread/OpenGLPipeline.cpp b/libs/hwui/renderthread/OpenGLPipeline.cpp
index 1ad3803..cca0fca 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.cpp
+++ b/libs/hwui/renderthread/OpenGLPipeline.cpp
@@ -165,6 +165,10 @@
}
void OpenGLPipeline::onDestroyHardwareResources() {
+ Caches& caches = Caches::getInstance();
+ // Make sure to release all the textures we were owning as there won't
+ // be another draw
+ caches.textureCache.resetMarkInUse(this);
mRenderThread.renderState().flush(Caches::FlushMode::Layers);
}
@@ -225,6 +229,21 @@
}
}
+void OpenGLPipeline::prepareToDraw(const RenderThread& thread, Bitmap* bitmap) {
+ if (Caches::hasInstance() && thread.eglManager().hasEglContext()) {
+ ATRACE_NAME("Bitmap#prepareToDraw task");
+ Caches::getInstance().textureCache.prefetch(bitmap);
+ }
+}
+
+void OpenGLPipeline::invokeFunctor(const RenderThread& thread, Functor* functor) {
+ DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext;
+ if (thread.eglManager().hasEglContext()) {
+ mode = DrawGlInfo::kModeProcess;
+ }
+ thread.renderState().invokeFunctor(functor, mode, nullptr);
+}
+
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/renderthread/OpenGLPipeline.h b/libs/hwui/renderthread/OpenGLPipeline.h
index 2f661dc..8722d59 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.h
+++ b/libs/hwui/renderthread/OpenGLPipeline.h
@@ -56,6 +56,8 @@
bool createOrUpdateLayer(RenderNode* node,
const DamageAccumulator& damageAccumulator) override;
static void destroyLayer(RenderNode* node);
+ static void prepareToDraw(const RenderThread& thread, Bitmap* bitmap);
+ static void invokeFunctor(const RenderThread& thread, Functor* functor);
private:
EglManager& mEglManager;
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 42da293..6cb2b9c 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -618,10 +618,7 @@
}
CREATE_BRIDGE2(prepareToDraw, RenderThread* thread, Bitmap* bitmap) {
- if (Caches::hasInstance() && args->thread->eglManager().hasEglContext()) {
- ATRACE_NAME("Bitmap#prepareToDraw task");
- Caches::getInstance().textureCache.prefetch(args->bitmap);
- }
+ CanvasContext::prepareToDraw(*args->thread, args->bitmap);
args->bitmap->unref();
args->bitmap = nullptr;
return nullptr;
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index c914098..d8677e13 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -89,8 +89,8 @@
void pushBackFrameCallback(IFrameCallback* callback);
TimeLord& timeLord() { return mTimeLord; }
- RenderState& renderState() { return *mRenderState; }
- EglManager& eglManager() { return *mEglManager; }
+ RenderState& renderState() const { return *mRenderState; }
+ EglManager& eglManager() const { return *mEglManager; }
JankTracker& jankTracker() { return *mJankTracker; }
const DisplayInfo& mainDisplayInfo() { return mDisplayInfo; }
diff --git a/libs/hwui/tests/unit/CanvasContextTests.cpp b/libs/hwui/tests/unit/CanvasContextTests.cpp
new file mode 100644
index 0000000..3cc7189
--- /dev/null
+++ b/libs/hwui/tests/unit/CanvasContextTests.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "AnimationContext.h"
+#include "IContextFactory.h"
+#include "renderthread/CanvasContext.h"
+#include "tests/common/TestUtils.h"
+
+using namespace android;
+using namespace android::uirenderer;
+using namespace android::uirenderer::renderthread;
+
+class ContextFactory : public IContextFactory {
+public:
+ virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) override {
+ return new AnimationContext(clock);
+ }
+};
+
+RENDERTHREAD_TEST(CanvasContext, create) {
+ auto rootNode = TestUtils::createNode(0, 0, 200, 400, nullptr);
+ ContextFactory contextFactory;
+ std::unique_ptr<CanvasContext> canvasContext(CanvasContext::create(
+ renderThread, false, rootNode.get(), &contextFactory));
+
+ ASSERT_FALSE(canvasContext->hasSurface());
+
+ canvasContext->destroy(nullptr);
+}
+
+class TestFunctor : public Functor {
+public:
+ bool didProcess = false;
+
+ virtual status_t operator ()(int what, void* data) {
+ if (what == DrawGlInfo::kModeProcess) { didProcess = true; }
+ return DrawGlInfo::kStatusDone;
+ }
+};
+
+RENDERTHREAD_TEST(CanvasContext, invokeFunctor) {
+ TestFunctor functor;
+ ASSERT_FALSE(functor.didProcess);
+ CanvasContext::invokeFunctor(renderThread, &functor);
+ ASSERT_TRUE(functor.didProcess);
+}