Enable RenderNode and RecordingCanvas for layoutlib
Bug: 117921091
Test: all tests should pass
Change-Id: I574b12a5f7a6a54cbbcb17c35a3884368fd404e6
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index d6f5c23a6..640b8f9 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -40,6 +40,8 @@
"android_graphics_Picture.cpp",
"android_nio_utils.cpp",
"android_util_PathParser.cpp",
+ "android_view_DisplayListCanvas.cpp",
+ "android_view_RenderNode.cpp",
"android/graphics/Bitmap.cpp",
"android/graphics/BitmapFactory.cpp",
"android/graphics/ByteBufferStreamAdaptor.cpp",
@@ -136,7 +138,6 @@
"android_database_SQLiteDebug.cpp",
"android_view_CompositionSamplingListener.cpp",
"android_view_DisplayEventReceiver.cpp",
- "android_view_DisplayListCanvas.cpp",
"android_view_TextureLayer.cpp",
"android_view_InputChannel.cpp",
"android_view_InputDevice.cpp",
@@ -147,7 +148,6 @@
"android_view_KeyEvent.cpp",
"android_view_MotionEvent.cpp",
"android_view_PointerIcon.cpp",
- "android_view_RenderNode.cpp",
"android_view_RenderNodeAnimator.cpp",
"android_view_Surface.cpp",
"android_view_SurfaceControl.cpp",
diff --git a/core/jni/LayoutlibLoader.cpp b/core/jni/LayoutlibLoader.cpp
index b172809..dd5113c 100644
--- a/core/jni/LayoutlibLoader.cpp
+++ b/core/jni/LayoutlibLoader.cpp
@@ -67,6 +67,8 @@
extern int register_android_graphics_text_LineBreaker(JNIEnv* env);
extern int register_android_graphics_text_MeasuredText(JNIEnv* env);
extern int register_android_util_PathParser(JNIEnv* env);
+extern int register_android_view_RenderNode(JNIEnv* env);
+extern int register_android_view_DisplayListCanvas(JNIEnv* env);
extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env);
extern int register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper(JNIEnv *env);
@@ -83,6 +85,7 @@
{"android.graphics.BitmapFactory", REG_JNI(register_android_graphics_BitmapFactory)},
{"android.graphics.ByteBufferStreamAdaptor", REG_JNI(register_android_graphics_ByteBufferStreamAdaptor)},
{"android.graphics.Canvas", REG_JNI(register_android_graphics_Canvas)},
+ {"android.graphics.RenderNode", REG_JNI(register_android_view_RenderNode)},
{"android.graphics.ColorFilter", REG_JNI(register_android_graphics_ColorFilter)},
{"android.graphics.ColorSpace", REG_JNI(register_android_graphics_ColorSpace)},
{"android.graphics.CreateJavaOutputStreamAdaptor", REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor)},
@@ -98,6 +101,7 @@
{"android.graphics.PathEffect", REG_JNI(register_android_graphics_PathEffect)},
{"android.graphics.PathMeasure", REG_JNI(register_android_graphics_PathMeasure)},
{"android.graphics.Picture", REG_JNI(register_android_graphics_Picture)},
+ {"android.graphics.RecordingCanvas", REG_JNI(register_android_view_DisplayListCanvas)},
{"android.graphics.Region", REG_JNI(register_android_graphics_Region)},
{"android.graphics.Shader", REG_JNI(register_android_graphics_Shader)},
{"android.graphics.Typeface", REG_JNI(register_android_graphics_Typeface)},
diff --git a/core/jni/android_view_DisplayListCanvas.cpp b/core/jni/android_view_DisplayListCanvas.cpp
index 40a133b..9907da5 100644
--- a/core/jni/android_view_DisplayListCanvas.cpp
+++ b/core/jni/android_view_DisplayListCanvas.cpp
@@ -21,9 +21,9 @@
#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
-
+#ifdef __ANDROID__ // Layoutlib does not support Looper and device properties
#include <utils/Looper.h>
-#include <cutils/properties.h>
+#endif
#include <SkBitmap.h>
#include <SkRegion.h>
@@ -34,7 +34,9 @@
#include <hwui/Canvas.h>
#include <hwui/Paint.h>
#include <minikin/Layout.h>
+#ifdef __ANDROID__ // Layoutlib does not support RenderThread
#include <renderthread/RenderProxy.h>
+#endif
#include "core_jni_helpers.h"
@@ -52,6 +54,7 @@
return env;
}
+#ifdef __ANDROID__ // Layoutlib does not support GL, Looper
class InvokeRunnableMessage : public MessageHandler {
public:
InvokeRunnableMessage(JNIEnv* env, jobject runnable) {
@@ -87,11 +90,13 @@
sp<Looper> mLooper;
sp<InvokeRunnableMessage> mMessage;
};
+#endif
// ---------------- @FastNative -----------------------------
static void android_view_DisplayListCanvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
jlong canvasPtr, jlong functorPtr, jobject releasedCallback) {
+#ifdef __ANDROID__ // Layoutlib does not support GL
Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
Functor* functor = reinterpret_cast<Functor*>(functorPtr);
sp<GlFunctorReleasedCallbackBridge> bridge;
@@ -99,52 +104,57 @@
bridge = new GlFunctorReleasedCallbackBridge(env, releasedCallback);
}
canvas->callDrawGLFunction(functor, bridge.get());
+#endif
}
// ---------------- @CriticalNative -------------------------
-static jlong android_view_DisplayListCanvas_createDisplayListCanvas(jlong renderNodePtr,
+static jlong android_view_DisplayListCanvas_createDisplayListCanvas(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
jint width, jint height) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return reinterpret_cast<jlong>(Canvas::create_recording_canvas(width, height, renderNode));
}
-static void android_view_DisplayListCanvas_resetDisplayListCanvas(jlong canvasPtr,
+static void android_view_DisplayListCanvas_resetDisplayListCanvas(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,
jlong renderNodePtr, jint width, jint height) {
Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
canvas->resetRecording(width, height, renderNode);
}
-static jint android_view_DisplayListCanvas_getMaxTextureSize() {
+static jint android_view_DisplayListCanvas_getMaxTextureSize(CRITICAL_JNI_PARAMS) {
+#ifdef __ANDROID__ // Layoutlib does not support RenderProxy (RenderThread)
return android::uirenderer::renderthread::RenderProxy::maxTextureSize();
+#else
+ return 4096;
+#endif
}
-static void android_view_DisplayListCanvas_insertReorderBarrier(jlong canvasPtr,
+static void android_view_DisplayListCanvas_insertReorderBarrier(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,
jboolean reorderEnable) {
Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
canvas->insertReorderBarrier(reorderEnable);
}
-static jlong android_view_DisplayListCanvas_finishRecording(jlong canvasPtr) {
+static jlong android_view_DisplayListCanvas_finishRecording(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr) {
Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
return reinterpret_cast<jlong>(canvas->finishRecording());
}
-static void android_view_DisplayListCanvas_drawRenderNode(jlong canvasPtr, jlong renderNodePtr) {
+static void android_view_DisplayListCanvas_drawRenderNode(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr, jlong renderNodePtr) {
Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
canvas->drawRenderNode(renderNode);
}
-static void android_view_DisplayListCanvas_drawTextureLayer(jlong canvasPtr, jlong layerPtr) {
+static void android_view_DisplayListCanvas_drawTextureLayer(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr, jlong layerPtr) {
Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
canvas->drawLayer(layer);
}
-static void android_view_DisplayListCanvas_drawRoundRectProps(jlong canvasPtr,
+static void android_view_DisplayListCanvas_drawRoundRectProps(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,
jlong leftPropPtr, jlong topPropPtr, jlong rightPropPtr, jlong bottomPropPtr,
jlong rxPropPtr, jlong ryPropPtr, jlong paintPropPtr) {
Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
@@ -158,7 +168,7 @@
canvas->drawRoundRect(leftProp, topProp, rightProp, bottomProp, rxProp, ryProp, paintProp);
}
-static void android_view_DisplayListCanvas_drawCircleProps(jlong canvasPtr,
+static void android_view_DisplayListCanvas_drawCircleProps(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,
jlong xPropPtr, jlong yPropPtr, jlong radiusPropPtr, jlong paintPropPtr) {
Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr);
@@ -168,7 +178,7 @@
canvas->drawCircle(xProp, yProp, radiusProp, paintProp);
}
-static void android_view_DisplayListCanvas_drawWebViewFunctor(jlong canvasPtr, jint functor) {
+static void android_view_DisplayListCanvas_drawWebViewFunctor(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr, jint functor) {
Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
canvas->drawWebViewFunctor(functor);
}
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index 43c0bbe..9450bc9 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -16,9 +16,9 @@
#define LOG_TAG "OpenGLRenderer"
#define ATRACE_TAG ATRACE_TAG_VIEW
-
+#ifdef __ANDROID__ // Layoutlib does not support EGL
#include <EGL/egl.h>
-
+#endif
#include "jni.h"
#include "GraphicsJNI.h"
#include <nativehelper/JNIHelp.h>
@@ -28,7 +28,9 @@
#include <DamageAccumulator.h>
#include <Matrix.h>
#include <RenderNode.h>
+#ifdef __ANDROID__ // Layoutlib does not support CanvasContext
#include <renderthread/CanvasContext.h>
+#endif
#include <TreeInfo.h>
#include <hwui/Paint.h>
#include <utils/TraceUtils.h>
@@ -85,7 +87,7 @@
renderNode->setStagingDisplayList(newData);
}
-static jboolean android_view_RenderNode_isValid(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_isValid(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
return reinterpret_cast<RenderNode*>(renderNodePtr)->isValid();
}
@@ -93,52 +95,52 @@
// RenderProperties - setters
// ----------------------------------------------------------------------------
-static jboolean android_view_RenderNode_setLayerType(jlong renderNodePtr, jint jlayerType) {
+static jboolean android_view_RenderNode_setLayerType(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jint jlayerType) {
LayerType layerType = static_cast<LayerType>(jlayerType);
return SET_AND_DIRTY(mutateLayerProperties().setType, layerType, RenderNode::GENERIC);
}
-static jboolean android_view_RenderNode_setLayerPaint(jlong renderNodePtr, jlong paintPtr) {
+static jboolean android_view_RenderNode_setLayerPaint(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jlong paintPtr) {
Paint* paint = reinterpret_cast<Paint*>(paintPtr);
return SET_AND_DIRTY(mutateLayerProperties().setFromPaint, paint, RenderNode::GENERIC);
}
-static jboolean android_view_RenderNode_setStaticMatrix(jlong renderNodePtr, jlong matrixPtr) {
+static jboolean android_view_RenderNode_setStaticMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jlong matrixPtr) {
SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
return SET_AND_DIRTY(setStaticMatrix, matrix, RenderNode::GENERIC);
}
-static jboolean android_view_RenderNode_setAnimationMatrix(jlong renderNodePtr, jlong matrixPtr) {
+static jboolean android_view_RenderNode_setAnimationMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jlong matrixPtr) {
SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
return SET_AND_DIRTY(setAnimationMatrix, matrix, RenderNode::GENERIC);
}
-static jboolean android_view_RenderNode_setClipToBounds(jlong renderNodePtr,
+static jboolean android_view_RenderNode_setClipToBounds(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
jboolean clipToBounds) {
return SET_AND_DIRTY(setClipToBounds, clipToBounds, RenderNode::GENERIC);
}
-static jboolean android_view_RenderNode_setClipBounds(jlong renderNodePtr,
+static jboolean android_view_RenderNode_setClipBounds(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
jint left, jint top, jint right, jint bottom) {
android::uirenderer::Rect clipBounds(left, top, right, bottom);
return SET_AND_DIRTY(setClipBounds, clipBounds, RenderNode::GENERIC);
}
-static jboolean android_view_RenderNode_setClipBoundsEmpty(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_setClipBoundsEmpty(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
return SET_AND_DIRTY(setClipBoundsEmpty,, RenderNode::GENERIC);
}
-static jboolean android_view_RenderNode_setProjectBackwards(jlong renderNodePtr,
+static jboolean android_view_RenderNode_setProjectBackwards(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
jboolean shouldProject) {
return SET_AND_DIRTY(setProjectBackwards, shouldProject, RenderNode::GENERIC);
}
-static jboolean android_view_RenderNode_setProjectionReceiver(jlong renderNodePtr,
+static jboolean android_view_RenderNode_setProjectionReceiver(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
jboolean shouldRecieve) {
return SET_AND_DIRTY(setProjectionReceiver, shouldRecieve, RenderNode::GENERIC);
}
-static jboolean android_view_RenderNode_setOutlineRoundRect(jlong renderNodePtr,
+static jboolean android_view_RenderNode_setOutlineRoundRect(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
jint left, jint top, jint right, jint bottom, jfloat radius, jfloat alpha) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
renderNode->mutateStagingProperties().mutableOutline().setRoundRect(left, top, right, bottom,
@@ -147,7 +149,7 @@
return true;
}
-static jboolean android_view_RenderNode_setOutlineConvexPath(jlong renderNodePtr,
+static jboolean android_view_RenderNode_setOutlineConvexPath(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
jlong outlinePathPtr, jfloat alpha) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
SkPath* outlinePath = reinterpret_cast<SkPath*>(outlinePathPtr);
@@ -156,47 +158,47 @@
return true;
}
-static jboolean android_view_RenderNode_setOutlineEmpty(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_setOutlineEmpty(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
renderNode->mutateStagingProperties().mutableOutline().setEmpty();
renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
return true;
}
-static jboolean android_view_RenderNode_setOutlineNone(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_setOutlineNone(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
renderNode->mutateStagingProperties().mutableOutline().setNone();
renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
return true;
}
-static jboolean android_view_RenderNode_hasShadow(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_hasShadow(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return renderNode->stagingProperties().hasShadow();
}
-static jboolean android_view_RenderNode_setSpotShadowColor(jlong renderNodePtr, jint shadowColor) {
+static jboolean android_view_RenderNode_setSpotShadowColor(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jint shadowColor) {
return SET_AND_DIRTY(setSpotShadowColor,
static_cast<SkColor>(shadowColor), RenderNode::GENERIC);
}
-static jint android_view_RenderNode_getSpotShadowColor(jlong renderNodePtr) {
+static jint android_view_RenderNode_getSpotShadowColor(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return renderNode->stagingProperties().getSpotShadowColor();
}
-static jboolean android_view_RenderNode_setAmbientShadowColor(jlong renderNodePtr,
+static jboolean android_view_RenderNode_setAmbientShadowColor(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
jint shadowColor) {
return SET_AND_DIRTY(setAmbientShadowColor,
static_cast<SkColor>(shadowColor), RenderNode::GENERIC);
}
-static jint android_view_RenderNode_getAmbientShadowColor(jlong renderNodePtr) {
+static jint android_view_RenderNode_getAmbientShadowColor(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return renderNode->stagingProperties().getAmbientShadowColor();
}
-static jboolean android_view_RenderNode_setClipToOutline(jlong renderNodePtr,
+static jboolean android_view_RenderNode_setClipToOutline(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
jboolean clipToOutline) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
renderNode->mutateStagingProperties().mutableOutline().setShouldClip(clipToOutline);
@@ -204,7 +206,7 @@
return true;
}
-static jboolean android_view_RenderNode_setRevealClip(jlong renderNodePtr, jboolean shouldClip,
+static jboolean android_view_RenderNode_setRevealClip(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jboolean shouldClip,
jfloat x, jfloat y, jfloat radius) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
renderNode->mutateStagingProperties().mutableRevealClip().set(
@@ -213,106 +215,106 @@
return true;
}
-static jboolean android_view_RenderNode_setAlpha(jlong renderNodePtr, float alpha) {
+static jboolean android_view_RenderNode_setAlpha(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float alpha) {
return SET_AND_DIRTY(setAlpha, alpha, RenderNode::ALPHA);
}
-static jboolean android_view_RenderNode_setHasOverlappingRendering(jlong renderNodePtr,
+static jboolean android_view_RenderNode_setHasOverlappingRendering(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
bool hasOverlappingRendering) {
return SET_AND_DIRTY(setHasOverlappingRendering, hasOverlappingRendering,
RenderNode::GENERIC);
}
-static void android_view_RenderNode_setUsageHint(jlong renderNodePtr, jint usageHint) {
+static void android_view_RenderNode_setUsageHint(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jint usageHint) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
renderNode->setUsageHint(static_cast<UsageHint>(usageHint));
}
-static jboolean android_view_RenderNode_setElevation(jlong renderNodePtr, float elevation) {
+static jboolean android_view_RenderNode_setElevation(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float elevation) {
return SET_AND_DIRTY(setElevation, elevation, RenderNode::Z);
}
-static jboolean android_view_RenderNode_setTranslationX(jlong renderNodePtr, float tx) {
+static jboolean android_view_RenderNode_setTranslationX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float tx) {
return SET_AND_DIRTY(setTranslationX, tx, RenderNode::TRANSLATION_X | RenderNode::X);
}
-static jboolean android_view_RenderNode_setTranslationY(jlong renderNodePtr, float ty) {
+static jboolean android_view_RenderNode_setTranslationY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float ty) {
return SET_AND_DIRTY(setTranslationY, ty, RenderNode::TRANSLATION_Y | RenderNode::Y);
}
-static jboolean android_view_RenderNode_setTranslationZ(jlong renderNodePtr, float tz) {
+static jboolean android_view_RenderNode_setTranslationZ(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float tz) {
return SET_AND_DIRTY(setTranslationZ, tz, RenderNode::TRANSLATION_Z | RenderNode::Z);
}
-static jboolean android_view_RenderNode_setRotation(jlong renderNodePtr, float rotation) {
+static jboolean android_view_RenderNode_setRotation(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float rotation) {
return SET_AND_DIRTY(setRotation, rotation, RenderNode::ROTATION);
}
-static jboolean android_view_RenderNode_setRotationX(jlong renderNodePtr, float rx) {
+static jboolean android_view_RenderNode_setRotationX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float rx) {
return SET_AND_DIRTY(setRotationX, rx, RenderNode::ROTATION_X);
}
-static jboolean android_view_RenderNode_setRotationY(jlong renderNodePtr, float ry) {
+static jboolean android_view_RenderNode_setRotationY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float ry) {
return SET_AND_DIRTY(setRotationY, ry, RenderNode::ROTATION_Y);
}
-static jboolean android_view_RenderNode_setScaleX(jlong renderNodePtr, float sx) {
+static jboolean android_view_RenderNode_setScaleX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float sx) {
return SET_AND_DIRTY(setScaleX, sx, RenderNode::SCALE_X);
}
-static jboolean android_view_RenderNode_setScaleY(jlong renderNodePtr, float sy) {
+static jboolean android_view_RenderNode_setScaleY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float sy) {
return SET_AND_DIRTY(setScaleY, sy, RenderNode::SCALE_Y);
}
-static jboolean android_view_RenderNode_setPivotX(jlong renderNodePtr, float px) {
+static jboolean android_view_RenderNode_setPivotX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float px) {
return SET_AND_DIRTY(setPivotX, px, RenderNode::GENERIC);
}
-static jboolean android_view_RenderNode_setPivotY(jlong renderNodePtr, float py) {
+static jboolean android_view_RenderNode_setPivotY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float py) {
return SET_AND_DIRTY(setPivotY, py, RenderNode::GENERIC);
}
-static jboolean android_view_RenderNode_resetPivot(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_resetPivot(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
return SET_AND_DIRTY(resetPivot, /* void */, RenderNode::GENERIC);
}
-static jboolean android_view_RenderNode_setCameraDistance(jlong renderNodePtr, float distance) {
+static jboolean android_view_RenderNode_setCameraDistance(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float distance) {
return SET_AND_DIRTY(setCameraDistance, distance, RenderNode::GENERIC);
}
-static jboolean android_view_RenderNode_setLeft(jlong renderNodePtr, int left) {
+static jboolean android_view_RenderNode_setLeft(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, int left) {
return SET_AND_DIRTY(setLeft, left, RenderNode::X);
}
-static jboolean android_view_RenderNode_setTop(jlong renderNodePtr, int top) {
+static jboolean android_view_RenderNode_setTop(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, int top) {
return SET_AND_DIRTY(setTop, top, RenderNode::Y);
}
-static jboolean android_view_RenderNode_setRight(jlong renderNodePtr, int right) {
+static jboolean android_view_RenderNode_setRight(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, int right) {
return SET_AND_DIRTY(setRight, right, RenderNode::X);
}
-static jboolean android_view_RenderNode_setBottom(jlong renderNodePtr, int bottom) {
+static jboolean android_view_RenderNode_setBottom(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, int bottom) {
return SET_AND_DIRTY(setBottom, bottom, RenderNode::Y);
}
-static jint android_view_RenderNode_getLeft(jlong renderNodePtr) {
+static jint android_view_RenderNode_getLeft(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getLeft();
}
-static jint android_view_RenderNode_getTop(jlong renderNodePtr) {
+static jint android_view_RenderNode_getTop(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getTop();
}
-static jint android_view_RenderNode_getRight(jlong renderNodePtr) {
+static jint android_view_RenderNode_getRight(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getRight();
}
-static jint android_view_RenderNode_getBottom(jlong renderNodePtr) {
+static jint android_view_RenderNode_getBottom(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getBottom();
}
-static jboolean android_view_RenderNode_setLeftTopRightBottom(jlong renderNodePtr,
+static jboolean android_view_RenderNode_setLeftTopRightBottom(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
int left, int top, int right, int bottom) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
if (renderNode->mutateStagingProperties().setLeftTopRightBottom(left, top, right, bottom)) {
@@ -322,11 +324,11 @@
return false;
}
-static jboolean android_view_RenderNode_offsetLeftAndRight(jlong renderNodePtr, jint offset) {
+static jboolean android_view_RenderNode_offsetLeftAndRight(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jint offset) {
return SET_AND_DIRTY(offsetLeftRight, offset, RenderNode::X);
}
-static jboolean android_view_RenderNode_offsetTopAndBottom(jlong renderNodePtr, jint offset) {
+static jboolean android_view_RenderNode_offsetTopAndBottom(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jint offset) {
return SET_AND_DIRTY(offsetTopBottom, offset, RenderNode::Y);
}
@@ -334,12 +336,12 @@
// RenderProperties - getters
// ----------------------------------------------------------------------------
-static jboolean android_view_RenderNode_hasOverlappingRendering(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_hasOverlappingRendering(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return renderNode->stagingProperties().hasOverlappingRendering();
}
-static jboolean android_view_RenderNode_getAnimationMatrix(jlong renderNodePtr, jlong outMatrixPtr) {
+static jboolean android_view_RenderNode_getAnimationMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jlong outMatrixPtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr);
@@ -352,83 +354,83 @@
return JNI_FALSE;
}
-static jboolean android_view_RenderNode_getClipToBounds(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_getClipToBounds(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return renderNode->stagingProperties().getClipToBounds();
}
-static jboolean android_view_RenderNode_getClipToOutline(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_getClipToOutline(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return renderNode->stagingProperties().getOutline().getShouldClip();
}
-static jfloat android_view_RenderNode_getAlpha(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getAlpha(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return renderNode->stagingProperties().getAlpha();
}
-static jfloat android_view_RenderNode_getCameraDistance(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getCameraDistance(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return renderNode->stagingProperties().getCameraDistance();
}
-static jfloat android_view_RenderNode_getScaleX(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getScaleX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return renderNode->stagingProperties().getScaleX();
}
-static jfloat android_view_RenderNode_getScaleY(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getScaleY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return renderNode->stagingProperties().getScaleY();
}
-static jfloat android_view_RenderNode_getElevation(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getElevation(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return renderNode->stagingProperties().getElevation();
}
-static jfloat android_view_RenderNode_getTranslationX(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getTranslationX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return renderNode->stagingProperties().getTranslationX();
}
-static jfloat android_view_RenderNode_getTranslationY(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getTranslationY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return renderNode->stagingProperties().getTranslationY();
}
-static jfloat android_view_RenderNode_getTranslationZ(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getTranslationZ(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return renderNode->stagingProperties().getTranslationZ();
}
-static jfloat android_view_RenderNode_getRotation(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getRotation(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return renderNode->stagingProperties().getRotation();
}
-static jfloat android_view_RenderNode_getRotationX(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getRotationX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return renderNode->stagingProperties().getRotationX();
}
-static jfloat android_view_RenderNode_getRotationY(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getRotationY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return renderNode->stagingProperties().getRotationY();
}
-static jboolean android_view_RenderNode_isPivotExplicitlySet(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_isPivotExplicitlySet(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return renderNode->stagingProperties().isPivotExplicitlySet();
}
-static jboolean android_view_RenderNode_hasIdentityMatrix(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_hasIdentityMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
renderNode->mutateStagingProperties().updateMatrix();
return !renderNode->stagingProperties().hasTransformMatrix();
}
-static jint android_view_RenderNode_getLayerType(jlong renderNodePtr) {
+static jint android_view_RenderNode_getLayerType(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return static_cast<int>(renderNode->stagingProperties().layerProperties().type());
}
@@ -437,7 +439,7 @@
// RenderProperties - computed getters
// ----------------------------------------------------------------------------
-static void android_view_RenderNode_getTransformMatrix(jlong renderNodePtr, jlong outMatrixPtr) {
+static void getTransformMatrix(jlong renderNodePtr, jlong outMatrixPtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr);
@@ -451,10 +453,14 @@
}
}
-static void android_view_RenderNode_getInverseTransformMatrix(jlong renderNodePtr,
+static void android_view_RenderNode_getTransformMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jlong outMatrixPtr) {
+ getTransformMatrix(renderNodePtr, outMatrixPtr);
+}
+
+static void android_view_RenderNode_getInverseTransformMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
jlong outMatrixPtr) {
// load transform matrix
- android_view_RenderNode_getTransformMatrix(renderNodePtr, outMatrixPtr);
+ getTransformMatrix(renderNodePtr, outMatrixPtr);
SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr);
// return it inverted
@@ -464,35 +470,35 @@
}
}
-static jfloat android_view_RenderNode_getPivotX(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getPivotX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
renderNode->mutateStagingProperties().updateMatrix();
return renderNode->stagingProperties().getPivotX();
}
-static jfloat android_view_RenderNode_getPivotY(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getPivotY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
renderNode->mutateStagingProperties().updateMatrix();
return renderNode->stagingProperties().getPivotY();
}
-static jint android_view_RenderNode_getWidth(jlong renderNodePtr) {
+static jint android_view_RenderNode_getWidth(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getWidth();
}
-static jint android_view_RenderNode_getHeight(jlong renderNodePtr) {
+static jint android_view_RenderNode_getHeight(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getHeight();
}
-static jboolean android_view_RenderNode_setAllowForceDark(jlong renderNodePtr, jboolean allow) {
+static jboolean android_view_RenderNode_setAllowForceDark(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jboolean allow) {
return SET_AND_DIRTY(setAllowForceDark, allow, RenderNode::GENERIC);
}
-static jboolean android_view_RenderNode_getAllowForceDark(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_getAllowForceDark(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getAllowForceDark();
}
-static jlong android_view_RenderNode_getUniqueId(jlong renderNodePtr) {
+static jlong android_view_RenderNode_getUniqueId(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
return reinterpret_cast<RenderNode*>(renderNodePtr)->uniqueId();
}
@@ -558,6 +564,7 @@
}
mPreviousPosition = bounds;
+#ifdef __ANDROID__ // Layoutlib does not support CanvasContext
incStrong(0);
auto functor = std::bind(
std::mem_fn(&PositionListenerTrampoline::doUpdatePositionAsync), this,
@@ -566,6 +573,7 @@
(jint) bounds.right, (jint) bounds.bottom);
info.canvasContext.enqueueFrameWork(std::move(functor));
+#endif
}
virtual void onPositionLost(RenderNode& node, const TreeInfo* info) override {
@@ -584,10 +592,11 @@
mWeakRef = nullptr;
return;
}
-
+#ifdef __ANDROID__ // Layoutlib does not support CanvasContext
// TODO: Remember why this is synchronous and then make a comment
env->CallVoidMethod(localref, gPositionListener_PositionLostMethod,
info ? info->canvasContext.getFrameNumber() : 0);
+#endif
env->DeleteLocalRef(localref);
}
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 354a4b3..5814bb7 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -56,6 +56,8 @@
host: {
include_dirs: [
"external/vulkan-headers/include",
+ "frameworks/native/libs/math/include",
+ "frameworks/native/libs/ui/include",
],
cflags: [
"-Wno-unused-variable",
@@ -159,6 +161,10 @@
whole_static_libs: ["libskia"],
srcs: [
+ "pipeline/skia/SkiaDisplayList.cpp",
+ "pipeline/skia/SkiaRecordingCanvas.cpp",
+ "pipeline/skia/RenderNodeDrawable.cpp",
+ "pipeline/skia/ReorderBarrierDrawables.cpp",
"hwui/AnimatedImageDrawable.cpp",
"hwui/AnimatedImageThread.cpp",
"hwui/Bitmap.cpp",
@@ -168,15 +174,24 @@
"hwui/PaintImpl.cpp",
"hwui/Typeface.cpp",
"utils/Blur.cpp",
+ "utils/Color.cpp",
"utils/LinearAllocator.cpp",
"utils/VectorDrawableUtils.cpp",
+ "AnimationContext.cpp",
"Animator.cpp",
+ "AnimatorManager.cpp",
+ "CanvasTransform.cpp",
+ "DamageAccumulator.cpp",
"Interpolator.cpp",
+ "LightingInfo.cpp",
"Matrix.cpp",
"PathParser.cpp",
"Properties.cpp",
"PropertyValuesAnimatorSet.cpp",
"PropertyValuesHolder.cpp",
+ "RecordingCanvas.cpp",
+ "RenderNode.cpp",
+ "RenderProperties.cpp",
"SkiaCanvas.cpp",
"VectorDrawable.cpp",
],
@@ -193,15 +208,11 @@
srcs: [
"pipeline/skia/GLFunctorDrawable.cpp",
"pipeline/skia/LayerDrawable.cpp",
- "pipeline/skia/RenderNodeDrawable.cpp",
- "pipeline/skia/ReorderBarrierDrawables.cpp",
"pipeline/skia/ShaderCache.cpp",
- "pipeline/skia/SkiaDisplayList.cpp",
"pipeline/skia/SkiaMemoryTracer.cpp",
"pipeline/skia/SkiaOpenGLPipeline.cpp",
"pipeline/skia/SkiaPipeline.cpp",
"pipeline/skia/SkiaProfileRenderer.cpp",
- "pipeline/skia/SkiaRecordingCanvas.cpp",
"pipeline/skia/SkiaVulkanPipeline.cpp",
"pipeline/skia/VectorDrawableAtlas.cpp",
"pipeline/skia/VkFunctorDrawable.cpp",
@@ -224,13 +235,8 @@
"surfacetexture/ImageConsumer.cpp",
"surfacetexture/SurfaceTexture.cpp",
"thread/CommonPool.cpp",
- "utils/Color.cpp",
"utils/GLUtils.cpp",
"utils/StringUtils.cpp",
- "AnimationContext.cpp",
- "AnimatorManager.cpp",
- "CanvasTransform.cpp",
- "DamageAccumulator.cpp",
"DeferredLayerUpdater.cpp",
"DeviceInfo.cpp",
"FrameInfo.cpp",
@@ -241,13 +247,9 @@
"JankTracker.cpp",
"Layer.cpp",
"LayerUpdateQueue.cpp",
- "LightingInfo.cpp",
"ProfileData.cpp",
"ProfileDataContainer.cpp",
"Readback.cpp",
- "RecordingCanvas.cpp",
- "RenderNode.cpp",
- "RenderProperties.cpp",
"TreeInfo.cpp",
"WebViewFunctorManager.cpp",
"protos/graphicsstats.proto",
@@ -257,6 +259,9 @@
cflags: ["-Wno-implicit-fallthrough"],
},
host: {
+ srcs: [
+ "utils/HostColorSpace.cpp",
+ ],
export_static_lib_headers: [
"libarect",
],
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index a833f7e..8aee8f5 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -20,7 +20,12 @@
#include "Debug.h"
#include "TreeInfo.h"
#include "VectorDrawable.h"
+#ifdef __ANDROID__
#include "renderthread/CanvasContext.h"
+#else
+#include "DamageAccumulator.h"
+#include "pipeline/skia/SkiaDisplayList.h"
+#endif
#include "utils/FatVector.h"
#include "utils/MathUtils.h"
#include "utils/StringUtils.h"
@@ -160,6 +165,7 @@
}
void RenderNode::pushLayerUpdate(TreeInfo& info) {
+#ifdef __ANDROID__ // Layoutlib does not support CanvasContext and Layers
LayerType layerType = properties().effectiveLayerType();
// If we are not a layer OR we cannot be rendered (eg, view was detached)
// we need to destroy any Layers we may have had previously
@@ -188,6 +194,7 @@
// That might be us, so tell CanvasContext that this layer is in the
// tree and should not be destroyed.
info.canvasContext.markLayerInUse(this);
+#endif
}
/**
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index e6710cc..e979448 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -526,9 +526,13 @@
}
bool fitsOnLayer() const {
+#ifdef __ANDROID__ // Layoutlib does not support device info
const DeviceInfo* deviceInfo = DeviceInfo::get();
return mPrimitiveFields.mWidth <= deviceInfo->maxTextureSize() &&
mPrimitiveFields.mHeight <= deviceInfo->maxTextureSize();
+#else
+ return mPrimitiveFields.mWidth <= 4096 && mPrimitiveFields.mHeight <= 4096;
+#endif
}
bool promotedToLayer() const {
diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp
index e2ddb91..a48c860 100644
--- a/libs/hwui/hwui/Canvas.cpp
+++ b/libs/hwui/hwui/Canvas.cpp
@@ -30,11 +30,7 @@
namespace android {
Canvas* Canvas::create_recording_canvas(int width, int height, uirenderer::RenderNode* renderNode) {
-#ifdef __ANDROID__ // Layoutlib does not support recording canvas
return new uirenderer::skiapipeline::SkiaRecordingCanvas(renderNode, width, height);
-#else
- return NULL;
-#endif
}
static inline void drawStroke(SkScalar left, SkScalar right, SkScalar top, SkScalar thickness,
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
index 780ac20..c7d5f31 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
@@ -17,9 +17,15 @@
#include "SkiaDisplayList.h"
#include "DumpOpsCanvas.h"
+#ifdef __ANDROID__ // Layoutlib does not support SkiaPipeline
#include "SkiaPipeline.h"
+#else
+#include "DamageAccumulator.h"
+#endif
#include "VectorDrawable.h"
+#ifdef __ANDROID__
#include "renderthread/CanvasContext.h"
+#endif
#include <SkImagePriv.h>
#include <SkPathOps.h>
@@ -81,6 +87,7 @@
// If the prepare tree is triggered by the UI thread and no previous call to
// pinImages has failed then we must pin all mutable images in the GPU cache
// until the next UI thread draw.
+#ifdef __ANDROID__ // Layoutlib does not support CanvasContext
if (info.prepareTextures && !info.canvasContext.pinImages(mMutableImages)) {
// In the event that pinning failed we prevent future pinImage calls for the
// remainder of this tree traversal and also unpin any currently pinned images
@@ -88,6 +95,7 @@
info.prepareTextures = false;
info.canvasContext.unpinImages();
}
+#endif
bool hasBackwardProjectedNodesHere = false;
bool hasBackwardProjectedNodesSubtree = false;
@@ -141,10 +149,12 @@
const SkRect& bounds = vectorDrawable->properties().getBounds();
if (intersects(info.screenSize, totalMatrix, bounds)) {
isDirty = true;
+#ifdef __ANDROID__ // Layoutlib does not support CanvasContext
static_cast<SkiaPipeline*>(info.canvasContext.getRenderPipeline())
->getVectorDrawables()
->push_back(vectorDrawable);
vectorDrawable->setPropertyChangeWillBeConsumed(true);
+#endif
}
}
}
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index 16c8b89..38ef131 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -18,14 +18,18 @@
#include <SkImagePriv.h>
#include "CanvasTransform.h"
+#ifdef __ANDROID__ // Layoutlib does not support Layers
#include "Layer.h"
#include "LayerDrawable.h"
+#endif
#include "NinePatchUtils.h"
#include "RenderNode.h"
#include "pipeline/skia/AnimatedDrawables.h"
+#ifdef __ANDROID__ // Layoutlib does not support GL, Vulcan etc.
#include "pipeline/skia/GLFunctorDrawable.h"
#include "pipeline/skia/VkFunctorDrawable.h"
#include "pipeline/skia/VkInteropFunctorDrawable.h"
+#endif
namespace android {
namespace uirenderer {
@@ -102,13 +106,16 @@
}
void SkiaRecordingCanvas::drawLayer(uirenderer::DeferredLayerUpdater* layerUpdater) {
+#ifdef __ANDROID__ // Layoutlib does not support Layers
if (layerUpdater != nullptr) {
// Create a ref-counted drawable, which is kept alive by sk_sp in SkLiteDL.
sk_sp<SkDrawable> drawable(new LayerDrawable(layerUpdater));
drawDrawable(drawable.get());
}
+#endif
}
+
void SkiaRecordingCanvas::drawRenderNode(uirenderer::RenderNode* renderNode) {
// Record the child node. Drawable dtor will be invoked when mChildNodes deque is cleared.
mDisplayList->mChildNodes.emplace_back(renderNode, asSkCanvas(), true, mCurrentBarrier);
@@ -125,8 +132,10 @@
}
}
+
void SkiaRecordingCanvas::callDrawGLFunction(Functor* functor,
uirenderer::GlFunctorLifecycleListener* listener) {
+#ifdef __ANDROID__ // Layoutlib does not support GL, Vulcan etc.
FunctorDrawable* functorDrawable;
if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
functorDrawable = mDisplayList->allocateDrawable<VkInteropFunctorDrawable>(
@@ -137,9 +146,11 @@
}
mDisplayList->mChildFunctors.push_back(functorDrawable);
drawDrawable(functorDrawable);
+#endif
}
void SkiaRecordingCanvas::drawWebViewFunctor(int functor) {
+#ifdef __ANDROID__ // Layoutlib does not support GL, Vulcan etc.
FunctorDrawable* functorDrawable;
if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
functorDrawable = mDisplayList->allocateDrawable<VkFunctorDrawable>(functor, asSkCanvas());
@@ -148,6 +159,7 @@
}
mDisplayList->mChildFunctors.push_back(functorDrawable);
drawDrawable(functorDrawable);
+#endif
}
void SkiaRecordingCanvas::drawVectorDrawable(VectorDrawableRoot* tree) {
diff --git a/libs/hwui/utils/HostColorSpace.cpp b/libs/hwui/utils/HostColorSpace.cpp
new file mode 100644
index 0000000..77a6820
--- /dev/null
+++ b/libs/hwui/utils/HostColorSpace.cpp
@@ -0,0 +1,417 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+// This is copied from framework/native/libs/ui in order not to include libui in host build
+
+#include <ui/ColorSpace.h>
+
+using namespace std::placeholders;
+
+namespace android {
+
+static constexpr float linearResponse(float v) {
+ return v;
+}
+
+static constexpr float rcpResponse(float x, const ColorSpace::TransferParameters& p) {
+ return x >= p.d * p.c ? (std::pow(x, 1.0f / p.g) - p.b) / p.a : x / p.c;
+}
+
+static constexpr float response(float x, const ColorSpace::TransferParameters& p) {
+ return x >= p.d ? std::pow(p.a * x + p.b, p.g) : p.c * x;
+}
+
+static constexpr float rcpFullResponse(float x, const ColorSpace::TransferParameters& p) {
+ return x >= p.d * p.c ? (std::pow(x - p.e, 1.0f / p.g) - p.b) / p.a : (x - p.f) / p.c;
+}
+
+static constexpr float fullResponse(float x, const ColorSpace::TransferParameters& p) {
+ return x >= p.d ? std::pow(p.a * x + p.b, p.g) + p.e : p.c * x + p.f;
+}
+
+static float absRcpResponse(float x, float g,float a, float b, float c, float d) {
+ float xx = std::abs(x);
+ return std::copysign(xx >= d * c ? (std::pow(xx, 1.0f / g) - b) / a : xx / c, x);
+}
+
+static float absResponse(float x, float g, float a, float b, float c, float d) {
+ float xx = std::abs(x);
+ return std::copysign(xx >= d ? std::pow(a * xx + b, g) : c * xx, x);
+}
+
+static float safePow(float x, float e) {
+ return powf(x < 0.0f ? 0.0f : x, e);
+}
+
+static ColorSpace::transfer_function toOETF(const ColorSpace::TransferParameters& parameters) {
+ if (parameters.e == 0.0f && parameters.f == 0.0f) {
+ return std::bind(rcpResponse, _1, parameters);
+ }
+ return std::bind(rcpFullResponse, _1, parameters);
+}
+
+static ColorSpace::transfer_function toEOTF( const ColorSpace::TransferParameters& parameters) {
+ if (parameters.e == 0.0f && parameters.f == 0.0f) {
+ return std::bind(response, _1, parameters);
+ }
+ return std::bind(fullResponse, _1, parameters);
+}
+
+static ColorSpace::transfer_function toOETF(float gamma) {
+ if (gamma == 1.0f) {
+ return linearResponse;
+ }
+ return std::bind(safePow, _1, 1.0f / gamma);
+}
+
+static ColorSpace::transfer_function toEOTF(float gamma) {
+ if (gamma == 1.0f) {
+ return linearResponse;
+ }
+ return std::bind(safePow, _1, gamma);
+}
+
+static constexpr std::array<float2, 3> computePrimaries(const mat3& rgbToXYZ) {
+ float3 r(rgbToXYZ * float3{1, 0, 0});
+ float3 g(rgbToXYZ * float3{0, 1, 0});
+ float3 b(rgbToXYZ * float3{0, 0, 1});
+
+ return {{r.xy / dot(r, float3{1}),
+ g.xy / dot(g, float3{1}),
+ b.xy / dot(b, float3{1})}};
+}
+
+static constexpr float2 computeWhitePoint(const mat3& rgbToXYZ) {
+ float3 w(rgbToXYZ * float3{1});
+ return w.xy / dot(w, float3{1});
+}
+
+ColorSpace::ColorSpace(
+ const std::string& name,
+ const mat3& rgbToXYZ,
+ transfer_function OETF,
+ transfer_function EOTF,
+ clamping_function clamper) noexcept
+ : mName(name)
+ , mRGBtoXYZ(rgbToXYZ)
+ , mXYZtoRGB(inverse(rgbToXYZ))
+ , mOETF(std::move(OETF))
+ , mEOTF(std::move(EOTF))
+ , mClamper(std::move(clamper))
+ , mPrimaries(computePrimaries(rgbToXYZ))
+ , mWhitePoint(computeWhitePoint(rgbToXYZ)) {
+}
+
+ColorSpace::ColorSpace(
+ const std::string& name,
+ const mat3& rgbToXYZ,
+ const TransferParameters parameters,
+ clamping_function clamper) noexcept
+ : mName(name)
+ , mRGBtoXYZ(rgbToXYZ)
+ , mXYZtoRGB(inverse(rgbToXYZ))
+ , mParameters(parameters)
+ , mOETF(toOETF(mParameters))
+ , mEOTF(toEOTF(mParameters))
+ , mClamper(std::move(clamper))
+ , mPrimaries(computePrimaries(rgbToXYZ))
+ , mWhitePoint(computeWhitePoint(rgbToXYZ)) {
+}
+
+ColorSpace::ColorSpace(
+ const std::string& name,
+ const mat3& rgbToXYZ,
+ float gamma,
+ clamping_function clamper) noexcept
+ : mName(name)
+ , mRGBtoXYZ(rgbToXYZ)
+ , mXYZtoRGB(inverse(rgbToXYZ))
+ , mParameters({gamma, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f})
+ , mOETF(toOETF(gamma))
+ , mEOTF(toEOTF(gamma))
+ , mClamper(std::move(clamper))
+ , mPrimaries(computePrimaries(rgbToXYZ))
+ , mWhitePoint(computeWhitePoint(rgbToXYZ)) {
+}
+
+ColorSpace::ColorSpace(
+ const std::string& name,
+ const std::array<float2, 3>& primaries,
+ const float2& whitePoint,
+ transfer_function OETF,
+ transfer_function EOTF,
+ clamping_function clamper) noexcept
+ : mName(name)
+ , mRGBtoXYZ(computeXYZMatrix(primaries, whitePoint))
+ , mXYZtoRGB(inverse(mRGBtoXYZ))
+ , mOETF(std::move(OETF))
+ , mEOTF(std::move(EOTF))
+ , mClamper(std::move(clamper))
+ , mPrimaries(primaries)
+ , mWhitePoint(whitePoint) {
+}
+
+ColorSpace::ColorSpace(
+ const std::string& name,
+ const std::array<float2, 3>& primaries,
+ const float2& whitePoint,
+ const TransferParameters parameters,
+ clamping_function clamper) noexcept
+ : mName(name)
+ , mRGBtoXYZ(computeXYZMatrix(primaries, whitePoint))
+ , mXYZtoRGB(inverse(mRGBtoXYZ))
+ , mParameters(parameters)
+ , mOETF(toOETF(mParameters))
+ , mEOTF(toEOTF(mParameters))
+ , mClamper(std::move(clamper))
+ , mPrimaries(primaries)
+ , mWhitePoint(whitePoint) {
+}
+
+ColorSpace::ColorSpace(
+ const std::string& name,
+ const std::array<float2, 3>& primaries,
+ const float2& whitePoint,
+ float gamma,
+ clamping_function clamper) noexcept
+ : mName(name)
+ , mRGBtoXYZ(computeXYZMatrix(primaries, whitePoint))
+ , mXYZtoRGB(inverse(mRGBtoXYZ))
+ , mParameters({gamma, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f})
+ , mOETF(toOETF(gamma))
+ , mEOTF(toEOTF(gamma))
+ , mClamper(std::move(clamper))
+ , mPrimaries(primaries)
+ , mWhitePoint(whitePoint) {
+}
+
+constexpr mat3 ColorSpace::computeXYZMatrix(
+ const std::array<float2, 3>& primaries, const float2& whitePoint) {
+ const float2& R = primaries[0];
+ const float2& G = primaries[1];
+ const float2& B = primaries[2];
+ const float2& W = whitePoint;
+
+ float oneRxRy = (1 - R.x) / R.y;
+ float oneGxGy = (1 - G.x) / G.y;
+ float oneBxBy = (1 - B.x) / B.y;
+ float oneWxWy = (1 - W.x) / W.y;
+
+ float RxRy = R.x / R.y;
+ float GxGy = G.x / G.y;
+ float BxBy = B.x / B.y;
+ float WxWy = W.x / W.y;
+
+ float BY =
+ ((oneWxWy - oneRxRy) * (GxGy - RxRy) - (WxWy - RxRy) * (oneGxGy - oneRxRy)) /
+ ((oneBxBy - oneRxRy) * (GxGy - RxRy) - (BxBy - RxRy) * (oneGxGy - oneRxRy));
+ float GY = (WxWy - RxRy - BY * (BxBy - RxRy)) / (GxGy - RxRy);
+ float RY = 1 - GY - BY;
+
+ float RYRy = RY / R.y;
+ float GYGy = GY / G.y;
+ float BYBy = BY / B.y;
+
+ return {
+ float3{RYRy * R.x, RY, RYRy * (1 - R.x - R.y)},
+ float3{GYGy * G.x, GY, GYGy * (1 - G.x - G.y)},
+ float3{BYBy * B.x, BY, BYBy * (1 - B.x - B.y)}
+ };
+}
+
+const ColorSpace ColorSpace::sRGB() {
+ return {
+ "sRGB IEC61966-2.1",
+ {{float2{0.640f, 0.330f}, {0.300f, 0.600f}, {0.150f, 0.060f}}},
+ {0.3127f, 0.3290f},
+ {2.4f, 1 / 1.055f, 0.055f / 1.055f, 1 / 12.92f, 0.04045f, 0.0f, 0.0f}
+ };
+}
+
+const ColorSpace ColorSpace::linearSRGB() {
+ return {
+ "sRGB IEC61966-2.1 (Linear)",
+ {{float2{0.640f, 0.330f}, {0.300f, 0.600f}, {0.150f, 0.060f}}},
+ {0.3127f, 0.3290f}
+ };
+}
+
+const ColorSpace ColorSpace::extendedSRGB() {
+ return {
+ "scRGB-nl IEC 61966-2-2:2003",
+ {{float2{0.640f, 0.330f}, {0.300f, 0.600f}, {0.150f, 0.060f}}},
+ {0.3127f, 0.3290f},
+ std::bind(absRcpResponse, _1, 2.4f, 1 / 1.055f, 0.055f / 1.055f, 1 / 12.92f, 0.04045f),
+ std::bind(absResponse, _1, 2.4f, 1 / 1.055f, 0.055f / 1.055f, 1 / 12.92f, 0.04045f),
+ std::bind(clamp<float>, _1, -0.799f, 2.399f)
+ };
+}
+
+const ColorSpace ColorSpace::linearExtendedSRGB() {
+ return {
+ "scRGB IEC 61966-2-2:2003",
+ {{float2{0.640f, 0.330f}, {0.300f, 0.600f}, {0.150f, 0.060f}}},
+ {0.3127f, 0.3290f},
+ 1.0f,
+ std::bind(clamp<float>, _1, -0.5f, 7.499f)
+ };
+}
+
+const ColorSpace ColorSpace::NTSC() {
+ return {
+ "NTSC (1953)",
+ {{float2{0.67f, 0.33f}, {0.21f, 0.71f}, {0.14f, 0.08f}}},
+ {0.310f, 0.316f},
+ {1 / 0.45f, 1 / 1.099f, 0.099f / 1.099f, 1 / 4.5f, 0.081f, 0.0f, 0.0f}
+ };
+}
+
+const ColorSpace ColorSpace::BT709() {
+ return {
+ "Rec. ITU-R BT.709-5",
+ {{float2{0.640f, 0.330f}, {0.300f, 0.600f}, {0.150f, 0.060f}}},
+ {0.3127f, 0.3290f},
+ {1 / 0.45f, 1 / 1.099f, 0.099f / 1.099f, 1 / 4.5f, 0.081f, 0.0f, 0.0f}
+ };
+}
+
+const ColorSpace ColorSpace::BT2020() {
+ return {
+ "Rec. ITU-R BT.2020-1",
+ {{float2{0.708f, 0.292f}, {0.170f, 0.797f}, {0.131f, 0.046f}}},
+ {0.3127f, 0.3290f},
+ {1 / 0.45f, 1 / 1.099f, 0.099f / 1.099f, 1 / 4.5f, 0.081f, 0.0f, 0.0f}
+ };
+}
+
+const ColorSpace ColorSpace::AdobeRGB() {
+ return {
+ "Adobe RGB (1998)",
+ {{float2{0.64f, 0.33f}, {0.21f, 0.71f}, {0.15f, 0.06f}}},
+ {0.3127f, 0.3290f},
+ 2.2f
+ };
+}
+
+const ColorSpace ColorSpace::ProPhotoRGB() {
+ return {
+ "ROMM RGB ISO 22028-2:2013",
+ {{float2{0.7347f, 0.2653f}, {0.1596f, 0.8404f}, {0.0366f, 0.0001f}}},
+ {0.34567f, 0.35850f},
+ {1.8f, 1.0f, 0.0f, 1 / 16.0f, 0.031248f, 0.0f, 0.0f}
+ };
+}
+
+const ColorSpace ColorSpace::DisplayP3() {
+ return {
+ "Display P3",
+ {{float2{0.680f, 0.320f}, {0.265f, 0.690f}, {0.150f, 0.060f}}},
+ {0.3127f, 0.3290f},
+ {2.4f, 1 / 1.055f, 0.055f / 1.055f, 1 / 12.92f, 0.039f, 0.0f, 0.0f}
+ };
+}
+
+const ColorSpace ColorSpace::DCIP3() {
+ return {
+ "SMPTE RP 431-2-2007 DCI (P3)",
+ {{float2{0.680f, 0.320f}, {0.265f, 0.690f}, {0.150f, 0.060f}}},
+ {0.314f, 0.351f},
+ 2.6f
+ };
+}
+
+const ColorSpace ColorSpace::ACES() {
+ return {
+ "SMPTE ST 2065-1:2012 ACES",
+ {{float2{0.73470f, 0.26530f}, {0.0f, 1.0f}, {0.00010f, -0.0770f}}},
+ {0.32168f, 0.33767f},
+ 1.0f,
+ std::bind(clamp<float>, _1, -65504.0f, 65504.0f)
+ };
+}
+
+const ColorSpace ColorSpace::ACEScg() {
+ return {
+ "Academy S-2014-004 ACEScg",
+ {{float2{0.713f, 0.293f}, {0.165f, 0.830f}, {0.128f, 0.044f}}},
+ {0.32168f, 0.33767f},
+ 1.0f,
+ std::bind(clamp<float>, _1, -65504.0f, 65504.0f)
+ };
+}
+
+std::unique_ptr<float3[]> ColorSpace::createLUT(uint32_t size, const ColorSpace& src,
+ const ColorSpace& dst) {
+ size = clamp(size, 2u, 256u);
+ float m = 1.0f / float(size - 1);
+
+ std::unique_ptr<float3[]> lut(new float3[size * size * size]);
+ float3* data = lut.get();
+
+ ColorSpaceConnector connector(src, dst);
+
+ for (uint32_t z = 0; z < size; z++) {
+ for (int32_t y = int32_t(size - 1); y >= 0; y--) {
+ for (uint32_t x = 0; x < size; x++) {
+ *data++ = connector.transform({x * m, y * m, z * m});
+ }
+ }
+ }
+
+ return lut;
+}
+
+static const float2 ILLUMINANT_D50_XY = {0.34567f, 0.35850f};
+static const float3 ILLUMINANT_D50_XYZ = {0.964212f, 1.0f, 0.825188f};
+static const mat3 BRADFORD = mat3{
+ float3{ 0.8951f, -0.7502f, 0.0389f},
+ float3{ 0.2664f, 1.7135f, -0.0685f},
+ float3{-0.1614f, 0.0367f, 1.0296f}
+};
+
+static mat3 adaptation(const mat3& matrix, const float3& srcWhitePoint, const float3& dstWhitePoint) {
+ float3 srcLMS = matrix * srcWhitePoint;
+ float3 dstLMS = matrix * dstWhitePoint;
+ return inverse(matrix) * mat3{dstLMS / srcLMS} * matrix;
+}
+
+ColorSpaceConnector::ColorSpaceConnector(
+ const ColorSpace& src,
+ const ColorSpace& dst) noexcept
+ : mSource(src)
+ , mDestination(dst) {
+
+ if (all(lessThan(abs(src.getWhitePoint() - dst.getWhitePoint()), float2{1e-3f}))) {
+ mTransform = dst.getXYZtoRGB() * src.getRGBtoXYZ();
+ } else {
+ mat3 rgbToXYZ(src.getRGBtoXYZ());
+ mat3 xyzToRGB(dst.getXYZtoRGB());
+
+ float3 srcXYZ = ColorSpace::XYZ(float3{src.getWhitePoint(), 1});
+ float3 dstXYZ = ColorSpace::XYZ(float3{dst.getWhitePoint(), 1});
+
+ if (any(greaterThan(abs(src.getWhitePoint() - ILLUMINANT_D50_XY), float2{1e-3f}))) {
+ rgbToXYZ = adaptation(BRADFORD, srcXYZ, ILLUMINANT_D50_XYZ) * src.getRGBtoXYZ();
+ }
+
+ if (any(greaterThan(abs(dst.getWhitePoint() - ILLUMINANT_D50_XY), float2{1e-3f}))) {
+ xyzToRGB = inverse(adaptation(BRADFORD, dstXYZ, ILLUMINANT_D50_XYZ) * dst.getRGBtoXYZ());
+ }
+
+ mTransform = xyzToRGB * rgbToXYZ;
+ }
+}
+
+}; // namespace android