-
Notifications
You must be signed in to change notification settings - Fork 126
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
- Loading branch information
1 parent
1af72c1
commit 09dae79
Showing
15 changed files
with
1,660 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
This project contains code adapted from "The Android Open Source Project" licensed under the Apache License, Version 2.0 (the "License"): | ||
|
||
https://android.googlesource.com/platform/frameworks/base |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#pragma once | ||
#include <SkPoint3.h> | ||
|
||
// Adoption of frameworks/base/libs/hwui/Lighting.h | ||
|
||
namespace skiko { | ||
namespace node { | ||
|
||
struct LightGeometry { | ||
SkPoint3 center; | ||
float radius; | ||
}; | ||
|
||
struct LightInfo { | ||
float ambientShadowAlpha; | ||
float spotShadowAlpha; | ||
}; | ||
|
||
} // namespace node | ||
} // namespace skiko |
111 changes: 111 additions & 0 deletions
111
skiko/src/commonMain/cpp/common/include/node/RenderNode.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
#pragma once | ||
#include <optional> | ||
#include <SkBBHFactory.h> | ||
#include <SkCamera.h> | ||
#include <SkCanvas.h> | ||
#include <SkColor.h> | ||
#include <SkDrawable.h> | ||
#include <SkMatrix.h> | ||
#include <SkPaint.h> | ||
#include <SkPath.h> | ||
#include <SkPictureRecorder.h> | ||
#include <SkPoint.h> | ||
#include <SkRRect.h> | ||
#include <SkRect.h> | ||
#include <SkRefCnt.h> | ||
#include "Lighting.h" | ||
|
||
namespace skiko { | ||
namespace node { | ||
|
||
class RenderNodeContext; | ||
|
||
class RenderNode : public SkDrawable { | ||
public: | ||
RenderNode(const sk_sp<RenderNodeContext>& context); | ||
~RenderNode(); | ||
|
||
std::optional<SkPaint>& getLayerPaint() { return this->layerPaint; } | ||
void setLayerPaint(const std::optional<SkPaint>& layerPaint); | ||
const SkRect& getBounds() const { return this->bounds; } | ||
void setBounds(const SkRect& bounds); | ||
const SkPoint& getPivot() const { return this->pivot; } | ||
void setPivot(const SkPoint& pivot); | ||
float getAlpha() const { return this->alpha; } | ||
void setAlpha(float alpha); | ||
float getScaleX() const { return this->scaleX; } | ||
void setScaleX(float scaleX); | ||
float getScaleY() const { return this->scaleY; } | ||
void setScaleY(float scaleY); | ||
float getTranslationX() const { return this->translationX; } | ||
void setTranslationX(float translationX); | ||
float getTranslationY() const { return this->translationY; } | ||
void setTranslationY(float translationY); | ||
float getShadowElevation() const { return this->shadowElevation; } | ||
void setShadowElevation(float shadowElevation); | ||
SkColor getAmbientShadowColor() const { return this->ambientShadowColor; } | ||
void setAmbientShadowColor(SkColor ambientShadowColor); | ||
SkColor getSpotShadowColor() const { return this->spotShadowColor; } | ||
void setSpotShadowColor(SkColor spotShadowColor); | ||
float getRotationX() const { return this->rotationX; } | ||
void setRotationX(float rotationX); | ||
float getRotationY() const { return this->rotationY; } | ||
void setRotationY(float rotationY); | ||
float getRotationZ() const { return this->rotationZ; } | ||
void setRotationZ(float rotationZ); | ||
float getCameraDistance() const; | ||
void setCameraDistance(float cameraDistance); | ||
void setClipRect(const std::optional<SkRect>& clipRect); | ||
void setClipRRect(const std::optional<SkRRect>& clipRRect); | ||
void setClipPath(const std::optional<SkPath>& clipPath); | ||
bool getClip() const { return this->clip; } | ||
void setClip(bool clip); | ||
|
||
const SkMatrix& getMatrix(); | ||
|
||
SkCanvas * beginRecording(); | ||
void endRecording(); | ||
|
||
void drawInto(SkCanvas *canvas); | ||
|
||
// SkDrawable | ||
void onDraw(SkCanvas* canvas) override; | ||
SkRect onGetBounds() override; | ||
|
||
protected: | ||
sk_sp<SkPicture> onMakePictureSnapshot() override; | ||
|
||
private: | ||
void updateMatrix(); | ||
void drawShadow(SkCanvas *canvas, const LightGeometry& lightGeometry, const LightInfo& lightInfo); | ||
void setCameraLocation(float x, float y, float z); | ||
|
||
sk_sp<RenderNodeContext> context; | ||
|
||
SkBBHFactory *bbhFactory; | ||
SkPictureRecorder recorder; | ||
sk_sp<SkDrawable> contentCache; | ||
|
||
std::optional<SkPaint> layerPaint; | ||
SkRect bounds; | ||
SkPoint pivot; | ||
float alpha; | ||
float scaleX, scaleY; | ||
float translationX, translationY; | ||
float shadowElevation; | ||
SkColor ambientShadowColor; | ||
SkColor spotShadowColor; | ||
float rotationX, rotationY, rotationZ; | ||
std::optional<SkRect> clipRect; | ||
std::optional<SkRRect> clipRRect; | ||
std::optional<SkPath> clipPath; | ||
bool clip; | ||
|
||
SkMatrix transformMatrix; | ||
SkCamera3D transformCamera; | ||
bool matrixIdentity; | ||
bool matrixDirty; | ||
}; | ||
|
||
} // namespace node | ||
} // namespace skiko |
30 changes: 30 additions & 0 deletions
30
skiko/src/commonMain/cpp/common/include/node/RenderNodeContext.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#pragma once | ||
#include <SkRefCnt.h> | ||
#include "Lighting.h" | ||
|
||
namespace skiko { | ||
namespace node { | ||
|
||
class RenderNode; | ||
|
||
class RenderNodeContext : public SkRefCnt { | ||
public: | ||
RenderNodeContext(bool measureDrawBounds); | ||
|
||
bool shouldMeasureDrawBounds() const { return this->measureDrawBounds; } | ||
|
||
const LightGeometry& getLightGeometry() const { return this->lightGeometry; } | ||
const LightInfo& getLightInfo() const { return this->lightInfo; } | ||
void setLightingInfo( | ||
const LightGeometry& lightGeometry, | ||
const LightInfo& lightInfo | ||
); | ||
|
||
private: | ||
LightGeometry lightGeometry; | ||
LightInfo lightInfo; | ||
bool measureDrawBounds; | ||
}; | ||
|
||
} // namespace node | ||
} // namespace skiko |
Oops, something went wrong.