OSDN Git Service

Implement runtime switch to select default renderer mode
authorStan Iliev <stani@google.com>
Thu, 7 Jul 2016 16:35:54 +0000 (12:35 -0400)
committerStan Iliev <stani@google.com>
Thu, 7 Jul 2016 18:27:20 +0000 (14:27 -0400)
Add a system property debug.hwui.default_renderer, which allows
to set rendering mode to OpenGL (default), Skia OpenGL or Vulkan.

Change-Id: I8bca5bacc5108f77437e340ac61f2d8db8cc4c39

libs/hwui/Properties.cpp
libs/hwui/Properties.h
libs/hwui/renderthread/CanvasContext.cpp
libs/hwui/renderthread/CanvasContext.h
libs/hwui/renderthread/RenderProxy.cpp
libs/hwui/tests/unit/RenderNodeTests.cpp

index 112ba11..d0ae1d4 100644 (file)
@@ -63,6 +63,7 @@ int Properties::overrideSpotShadowStrength = -1;
 
 ProfileType Properties::sProfileType = ProfileType::None;
 bool Properties::sDisableProfileBars = false;
+RenderPipelineType Properties::sRenderPipelineType = RenderPipelineType::NotInitialized;
 
 bool Properties::waitForGpuCompletion = false;
 bool Properties::forceDrawFrame = false;
@@ -205,5 +206,21 @@ ProfileType Properties::getProfileType() {
     return sProfileType;
 }
 
+RenderPipelineType Properties::getRenderPipelineType() {
+    if (RenderPipelineType::NotInitialized != sRenderPipelineType) {
+        return sRenderPipelineType;
+    }
+    char prop[PROPERTY_VALUE_MAX];
+    property_get(PROPERTY_DEFAULT_RENDERER, prop, "opengl");
+    if (!strcmp(prop, "skiagl") ) {
+        sRenderPipelineType = RenderPipelineType::SkiaGL;
+    } else if (!strcmp(prop, "vulkan") ) {
+        sRenderPipelineType = RenderPipelineType::Vulkan;
+    } else { //"opengl"
+        sRenderPipelineType = RenderPipelineType::OpenGL;
+    }
+    return sRenderPipelineType;
+}
+
 }; // namespace uirenderer
 }; // namespace android
index cdfc081..880a90e 100644 (file)
@@ -153,6 +153,12 @@ enum DebugLevel {
 
 #define PROPERTY_FILTER_TEST_OVERHEAD "debug.hwui.filter_test_overhead"
 
+/**
+ * Allows to set rendering pipeline mode to OpenGL (default), Skia OpenGL
+ * or Vulkan.
+ */
+#define PROPERTY_DEFAULT_RENDERER "debug.hwui.default_renderer"
+
 ///////////////////////////////////////////////////////////////////////////////
 // Runtime configuration properties
 ///////////////////////////////////////////////////////////////////////////////
@@ -245,6 +251,13 @@ enum class StencilClipDebug {
     ShowRegion
 };
 
+enum class RenderPipelineType {
+    OpenGL = 0,
+    SkiaGL,
+    Vulkan,
+    NotInitialized = 128
+};
+
 /**
  * Renderthread-only singleton which manages several static rendering properties. Most of these
  * are driven by system properties which are queried once at initialization, and again if init()
@@ -292,6 +305,7 @@ public:
     static int overrideSpotShadowStrength;
 
     static ProfileType getProfileType();
+    static RenderPipelineType getRenderPipelineType();
 
     // Should be used only by test apps
     static bool waitForGpuCompletion;
@@ -304,6 +318,7 @@ public:
 private:
     static ProfileType sProfileType;
     static bool sDisableProfileBars;
+    static RenderPipelineType sRenderPipelineType;
 
 }; // class Caches
 
index 0a48a0c..582c3ea 100644 (file)
@@ -61,6 +61,28 @@ namespace android {
 namespace uirenderer {
 namespace renderthread {
 
+CanvasContext* CanvasContext::create(RenderThread& thread,
+        bool translucent, RenderNode* rootRenderNode, IContextFactory* contextFactory) {
+
+    auto renderType = Properties::getRenderPipelineType();
+    switch (renderType) {
+        case RenderPipelineType::OpenGL:
+            return new CanvasContext(thread, translucent, rootRenderNode, contextFactory);
+        case RenderPipelineType::SkiaGL:
+            //TODO: implement SKIA GL
+            LOG_ALWAYS_FATAL("skiaGL canvas type not implemented.");
+            break;
+        case RenderPipelineType::Vulkan:
+            //TODO: implement Vulkan
+            LOG_ALWAYS_FATAL("Vulkan canvas type not implemented.");
+            break;
+        default:
+            LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType);
+            break;
+    }
+    return nullptr;
+}
+
 CanvasContext::CanvasContext(RenderThread& thread, bool translucent,
         RenderNode* rootRenderNode, IContextFactory* contextFactory)
         : mRenderThread(thread)
@@ -789,6 +811,11 @@ int64_t CanvasContext::getFrameNumber() {
     return mFrameNumber;
 }
 
+bool CanvasContext::isSkiaEnabled() {
+    auto renderType = Properties::getRenderPipelineType();
+    return RenderPipelineType::SkiaGL == renderType || RenderPipelineType::Vulkan == renderType;
+}
+
 } /* namespace renderthread */
 } /* namespace uirenderer */
 } /* namespace android */
index 528e29e..3e3c6e6 100644 (file)
@@ -72,8 +72,8 @@ enum SwapBehavior {
 // TODO: Rename to Renderer or some other per-window, top-level manager
 class CanvasContext : public IFrameCallback {
 public:
-    CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
-            IContextFactory* contextFactory);
+    static CanvasContext* create(RenderThread& thread, bool translucent,
+            RenderNode* rootRenderNode, IContextFactory* contextFactory);
     virtual ~CanvasContext();
 
     // Won't take effect until next EGLSurface creation
@@ -107,6 +107,7 @@ public:
     static void trimMemory(RenderThread& thread, int level);
 
     static void invokeFunctor(RenderThread& thread, Functor* functor);
+    static bool isSkiaEnabled();
 
     Layer* createTextureLayer();
 
@@ -167,6 +168,9 @@ public:
     ANDROID_API int64_t getFrameNumber();
 
 private:
+    CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
+            IContextFactory* contextFactory);
+
     friend class RegisterFrameCallbackTask;
     // TODO: Replace with something better for layer & other GL object
     // lifecycle tracking
index 10a17f8..c689544 100644 (file)
@@ -55,7 +55,7 @@ namespace renderthread {
 
 CREATE_BRIDGE4(createContext, RenderThread* thread, bool translucent,
         RenderNode* rootRenderNode, IContextFactory* contextFactory) {
-    return new CanvasContext(*args->thread, args->translucent,
+    return CanvasContext::create(*args->thread, args->translucent,
             args->rootRenderNode, args->contextFactory);
 }
 
index fb5be0f..132601e 100644 (file)
@@ -105,8 +105,9 @@ TEST(RenderNode, releasedCallback) {
 
 RENDERTHREAD_TEST(RenderNode, prepareTree_nullableDisplayList) {
     ContextFactory contextFactory;
-    CanvasContext canvasContext(renderThread, false, nullptr, &contextFactory);
-    TreeInfo info(TreeInfo::MODE_RT_ONLY, canvasContext);
+    std::unique_ptr<CanvasContext> canvasContext(CanvasContext::create(
+            renderThread, false, nullptr, &contextFactory));
+    TreeInfo info(TreeInfo::MODE_RT_ONLY, *canvasContext.get());
     DamageAccumulator damageAccumulator;
     info.damageAccumulator = &damageAccumulator;
     info.observer = nullptr;
@@ -128,5 +129,5 @@ RENDERTHREAD_TEST(RenderNode, prepareTree_nullableDisplayList) {
         nullDLNode->prepareTree(info);
     }
 
-    canvasContext.destroy(nullptr);
+    canvasContext->destroy(nullptr);
 }