ProfileType Properties::sProfileType = ProfileType::None;
bool Properties::sDisableProfileBars = false;
+RenderPipelineType Properties::sRenderPipelineType = RenderPipelineType::NotInitialized;
bool Properties::waitForGpuCompletion = false;
bool Properties::forceDrawFrame = false;
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
#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
///////////////////////////////////////////////////////////////////////////////
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()
static int overrideSpotShadowStrength;
static ProfileType getProfileType();
+ static RenderPipelineType getRenderPipelineType();
// Should be used only by test apps
static bool waitForGpuCompletion;
private:
static ProfileType sProfileType;
static bool sDisableProfileBars;
+ static RenderPipelineType sRenderPipelineType;
}; // class Caches
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)
return mFrameNumber;
}
+bool CanvasContext::isSkiaEnabled() {
+ auto renderType = Properties::getRenderPipelineType();
+ return RenderPipelineType::SkiaGL == renderType || RenderPipelineType::Vulkan == renderType;
+}
+
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
// 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
static void trimMemory(RenderThread& thread, int level);
static void invokeFunctor(RenderThread& thread, Functor* functor);
+ static bool isSkiaEnabled();
Layer* createTextureLayer();
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
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);
}
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;
nullDLNode->prepareTree(info);
}
- canvasContext.destroy(nullptr);
+ canvasContext->destroy(nullptr);
}