Skip to content

Commit 09dae79

Browse files
authored
Adoption of RenderNode approach (#1014)
It is a simplified adoption of Android's `RenderNode`. ```kt /** * <p>RenderNode is used to build hardware accelerated rendering hierarchies. Each RenderNode * contains both a display list as well as a set of properties that affect the rendering of the * display list. RenderNodes are used internally for all Views by default and are not typically * used directly.</p> * * <p>RenderNodes are used to divide up the rendering content of a complex scene into smaller * pieces that can then be updated individually more cheaply. Updating part of the scene only needs * to update the display list or properties of a small number of RenderNode instead of redrawing * everything from scratch. A RenderNode only needs its display list re-recorded when its content * alone should be changed. RenderNodes can also be transformed without re-recording the display * list through the transform properties.</p> ``` This is a more correct approach to make `GraphicsLayer` in Compose invalidation independently. - Moved drawing callback to C++ side to avoid extra interop costs - Switched from `SkPicture` placeholder to custom `SkDrawable` implementation
1 parent 1af72c1 commit 09dae79

File tree

15 files changed

+1660
-1
lines changed

15 files changed

+1660
-1
lines changed

NOTICE

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
This project contains code adapted from "The Android Open Source Project" licensed under the Apache License, Version 2.0 (the "License"):
2+
3+
https://android.googlesource.com/platform/frameworks/base

skiko/buildSrc/src/main/kotlin/CompileSkikoCppTask.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import kotlin.collections.HashSet
1919

2020
abstract class CompileSkikoCppTask() : AbstractSkikoNativeToolTask() {
2121
@get:Internal
22-
open val srcExtensions: Array<String> = arrayOf("cc")
22+
open val srcExtensions: Array<String> = arrayOf("cc", "cpp")
2323

2424
@get:Internal
2525
open val headerExtensions: Array<String> = arrayOf("h", "hh")

skiko/src/commonMain/cpp/common/include/mppinterop.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace skikoMpp {
88
namespace skrect {
9+
// TODO: Combine with skija::Rect::copyToInterop
910
void serializeAs4Floats(const SkRect& rect, float* result);
1011
std::unique_ptr<SkRect> toSkRect(float* topLeftRightBottom);
1112
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#pragma once
2+
#include <SkPoint3.h>
3+
4+
// Adoption of frameworks/base/libs/hwui/Lighting.h
5+
6+
namespace skiko {
7+
namespace node {
8+
9+
struct LightGeometry {
10+
SkPoint3 center;
11+
float radius;
12+
};
13+
14+
struct LightInfo {
15+
float ambientShadowAlpha;
16+
float spotShadowAlpha;
17+
};
18+
19+
} // namespace node
20+
} // namespace skiko
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#pragma once
2+
#include <optional>
3+
#include <SkBBHFactory.h>
4+
#include <SkCamera.h>
5+
#include <SkCanvas.h>
6+
#include <SkColor.h>
7+
#include <SkDrawable.h>
8+
#include <SkMatrix.h>
9+
#include <SkPaint.h>
10+
#include <SkPath.h>
11+
#include <SkPictureRecorder.h>
12+
#include <SkPoint.h>
13+
#include <SkRRect.h>
14+
#include <SkRect.h>
15+
#include <SkRefCnt.h>
16+
#include "Lighting.h"
17+
18+
namespace skiko {
19+
namespace node {
20+
21+
class RenderNodeContext;
22+
23+
class RenderNode : public SkDrawable {
24+
public:
25+
RenderNode(const sk_sp<RenderNodeContext>& context);
26+
~RenderNode();
27+
28+
std::optional<SkPaint>& getLayerPaint() { return this->layerPaint; }
29+
void setLayerPaint(const std::optional<SkPaint>& layerPaint);
30+
const SkRect& getBounds() const { return this->bounds; }
31+
void setBounds(const SkRect& bounds);
32+
const SkPoint& getPivot() const { return this->pivot; }
33+
void setPivot(const SkPoint& pivot);
34+
float getAlpha() const { return this->alpha; }
35+
void setAlpha(float alpha);
36+
float getScaleX() const { return this->scaleX; }
37+
void setScaleX(float scaleX);
38+
float getScaleY() const { return this->scaleY; }
39+
void setScaleY(float scaleY);
40+
float getTranslationX() const { return this->translationX; }
41+
void setTranslationX(float translationX);
42+
float getTranslationY() const { return this->translationY; }
43+
void setTranslationY(float translationY);
44+
float getShadowElevation() const { return this->shadowElevation; }
45+
void setShadowElevation(float shadowElevation);
46+
SkColor getAmbientShadowColor() const { return this->ambientShadowColor; }
47+
void setAmbientShadowColor(SkColor ambientShadowColor);
48+
SkColor getSpotShadowColor() const { return this->spotShadowColor; }
49+
void setSpotShadowColor(SkColor spotShadowColor);
50+
float getRotationX() const { return this->rotationX; }
51+
void setRotationX(float rotationX);
52+
float getRotationY() const { return this->rotationY; }
53+
void setRotationY(float rotationY);
54+
float getRotationZ() const { return this->rotationZ; }
55+
void setRotationZ(float rotationZ);
56+
float getCameraDistance() const;
57+
void setCameraDistance(float cameraDistance);
58+
void setClipRect(const std::optional<SkRect>& clipRect);
59+
void setClipRRect(const std::optional<SkRRect>& clipRRect);
60+
void setClipPath(const std::optional<SkPath>& clipPath);
61+
bool getClip() const { return this->clip; }
62+
void setClip(bool clip);
63+
64+
const SkMatrix& getMatrix();
65+
66+
SkCanvas * beginRecording();
67+
void endRecording();
68+
69+
void drawInto(SkCanvas *canvas);
70+
71+
// SkDrawable
72+
void onDraw(SkCanvas* canvas) override;
73+
SkRect onGetBounds() override;
74+
75+
protected:
76+
sk_sp<SkPicture> onMakePictureSnapshot() override;
77+
78+
private:
79+
void updateMatrix();
80+
void drawShadow(SkCanvas *canvas, const LightGeometry& lightGeometry, const LightInfo& lightInfo);
81+
void setCameraLocation(float x, float y, float z);
82+
83+
sk_sp<RenderNodeContext> context;
84+
85+
SkBBHFactory *bbhFactory;
86+
SkPictureRecorder recorder;
87+
sk_sp<SkDrawable> contentCache;
88+
89+
std::optional<SkPaint> layerPaint;
90+
SkRect bounds;
91+
SkPoint pivot;
92+
float alpha;
93+
float scaleX, scaleY;
94+
float translationX, translationY;
95+
float shadowElevation;
96+
SkColor ambientShadowColor;
97+
SkColor spotShadowColor;
98+
float rotationX, rotationY, rotationZ;
99+
std::optional<SkRect> clipRect;
100+
std::optional<SkRRect> clipRRect;
101+
std::optional<SkPath> clipPath;
102+
bool clip;
103+
104+
SkMatrix transformMatrix;
105+
SkCamera3D transformCamera;
106+
bool matrixIdentity;
107+
bool matrixDirty;
108+
};
109+
110+
} // namespace node
111+
} // namespace skiko
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#pragma once
2+
#include <SkRefCnt.h>
3+
#include "Lighting.h"
4+
5+
namespace skiko {
6+
namespace node {
7+
8+
class RenderNode;
9+
10+
class RenderNodeContext : public SkRefCnt {
11+
public:
12+
RenderNodeContext(bool measureDrawBounds);
13+
14+
bool shouldMeasureDrawBounds() const { return this->measureDrawBounds; }
15+
16+
const LightGeometry& getLightGeometry() const { return this->lightGeometry; }
17+
const LightInfo& getLightInfo() const { return this->lightInfo; }
18+
void setLightingInfo(
19+
const LightGeometry& lightGeometry,
20+
const LightInfo& lightInfo
21+
);
22+
23+
private:
24+
LightGeometry lightGeometry;
25+
LightInfo lightInfo;
26+
bool measureDrawBounds;
27+
};
28+
29+
} // namespace node
30+
} // namespace skiko

0 commit comments

Comments
 (0)