Add a unique ID to rendernode
Bug: 120089776 Test: dump'd skp, verified ID present Change-Id: I97a03804ebc53925e1b79db3dd616a728eff0bfa
This commit is contained in:
@@ -14687,6 +14687,7 @@ package android.graphics {
|
||||
method public float getTranslationX();
|
||||
method public float getTranslationY();
|
||||
method public float getTranslationZ();
|
||||
method public long getUniqueId();
|
||||
method public int getWidth();
|
||||
method public boolean hasDisplayList();
|
||||
method public boolean hasIdentityMatrix();
|
||||
|
||||
@@ -468,6 +468,10 @@ static jboolean android_view_RenderNode_getAllowForceDark(jlong renderNodePtr) {
|
||||
return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getAllowForceDark();
|
||||
}
|
||||
|
||||
static jlong android_view_RenderNode_getUniqueId(jlong renderNodePtr) {
|
||||
return reinterpret_cast<RenderNode*>(renderNodePtr)->uniqueId();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// RenderProperties - Animations
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -694,6 +698,7 @@ static const JNINativeMethod gMethods[] = {
|
||||
{ "nGetHeight", "(J)I", (void*) android_view_RenderNode_getHeight },
|
||||
{ "nSetAllowForceDark", "(JZ)Z", (void*) android_view_RenderNode_setAllowForceDark },
|
||||
{ "nGetAllowForceDark", "(J)Z", (void*) android_view_RenderNode_getAllowForceDark },
|
||||
{ "nGetUniqueId", "(J)J", (void*) android_view_RenderNode_getUniqueId },
|
||||
};
|
||||
|
||||
int register_android_view_RenderNode(JNIEnv* env) {
|
||||
|
||||
@@ -1173,6 +1173,22 @@ public final class RenderNode {
|
||||
return nGetAllowForceDark(mNativeRenderNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unique ID that identifies this RenderNode. This ID is unique for the
|
||||
* lifetime of the process. IDs are reset on process death, and are unique only within
|
||||
* the process.
|
||||
*
|
||||
* This ID is intended to be used with debugging tools to associate a particular
|
||||
* RenderNode across different debug dumping & inspection tools. For example
|
||||
* a View layout inspector should include the unique ID for any RenderNodes that it owns
|
||||
* to associate the drawing content with the layout content.
|
||||
*
|
||||
* @return the unique ID for this RenderNode
|
||||
*/
|
||||
public long getUniqueId() {
|
||||
return nGetUniqueId(mNativeRenderNode);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Animations
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@@ -1479,4 +1495,7 @@ public final class RenderNode {
|
||||
|
||||
@CriticalNative
|
||||
private static native boolean nGetAllowForceDark(long renderNode);
|
||||
|
||||
@CriticalNative
|
||||
private static native long nGetUniqueId(long renderNode);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include <SkPathOps.h>
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
@@ -47,8 +48,14 @@ private:
|
||||
TreeInfo* mTreeInfo;
|
||||
};
|
||||
|
||||
static int64_t generateId() {
|
||||
static std::atomic<int64_t> sNextId{1};
|
||||
return sNextId++;
|
||||
}
|
||||
|
||||
RenderNode::RenderNode()
|
||||
: mDirtyPropertyFields(0)
|
||||
: mUniqueId(generateId())
|
||||
, mDirtyPropertyFields(0)
|
||||
, mNeedsDisplayListSync(false)
|
||||
, mDisplayList(nullptr)
|
||||
, mStagingDisplayList(nullptr)
|
||||
@@ -444,5 +451,38 @@ const SkPath* RenderNode::getClippedOutline(const SkRect& clipRect) const {
|
||||
return &mClippedOutlineCache.clippedOutline;
|
||||
}
|
||||
|
||||
using StringBuffer = FatVector<char, 128>;
|
||||
|
||||
template <typename... T>
|
||||
static void format(StringBuffer& buffer, const std::string_view& format, T... args) {
|
||||
buffer.resize(buffer.capacity());
|
||||
while (1) {
|
||||
int needed = snprintf(buffer.data(), buffer.size(),
|
||||
format.data(), std::forward<T>(args)...);
|
||||
if (needed < 0) {
|
||||
buffer[0] = '\0';
|
||||
buffer.resize(1);
|
||||
return;
|
||||
}
|
||||
if (needed < buffer.size()) {
|
||||
buffer.resize(needed + 1);
|
||||
return;
|
||||
}
|
||||
buffer.resize(buffer.size() * 2);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderNode::markDrawStart(SkCanvas& canvas) {
|
||||
StringBuffer buffer;
|
||||
format(buffer, "RenderNode(id=%d, name='%s')", uniqueId(), getName());
|
||||
canvas.drawAnnotation(SkRect::MakeWH(getWidth(), getHeight()), buffer.data(), nullptr);
|
||||
}
|
||||
|
||||
void RenderNode::markDrawEnd(SkCanvas& canvas) {
|
||||
StringBuffer buffer;
|
||||
format(buffer, "/RenderNode(id=%d, name='%s')", uniqueId(), getName());
|
||||
canvas.drawAnnotation(SkRect::MakeWH(getWidth(), getHeight()), buffer.data(), nullptr);
|
||||
}
|
||||
|
||||
} /* namespace uirenderer */
|
||||
} /* namespace android */
|
||||
|
||||
@@ -213,6 +213,11 @@ public:
|
||||
|
||||
UsageHint usageHint() const { return mUsageHint; }
|
||||
|
||||
int64_t uniqueId() const { return mUniqueId; }
|
||||
|
||||
void markDrawStart(SkCanvas& canvas);
|
||||
void markDrawEnd(SkCanvas& canvas);
|
||||
|
||||
private:
|
||||
void computeOrderingImpl(RenderNodeOp* opState,
|
||||
std::vector<RenderNodeOp*>* compositedChildrenOfProjectionSurface,
|
||||
@@ -233,6 +238,7 @@ private:
|
||||
void incParentRefCount() { mParentCount++; }
|
||||
void decParentRefCount(TreeObserver& observer, TreeInfo* info = nullptr);
|
||||
|
||||
const int64_t mUniqueId;
|
||||
String8 mName;
|
||||
sp<VirtualLightRefBase> mUserContext;
|
||||
|
||||
|
||||
@@ -115,12 +115,26 @@ void RenderNodeDrawable::onDraw(SkCanvas* canvas) {
|
||||
}
|
||||
}
|
||||
|
||||
class MarkDraw {
|
||||
public:
|
||||
explicit MarkDraw(SkCanvas& canvas, RenderNode& node) : mCanvas(canvas), mNode(node) {
|
||||
if (CC_UNLIKELY(Properties::skpCaptureEnabled)) {
|
||||
mNode.markDrawStart(mCanvas);
|
||||
}
|
||||
}
|
||||
~MarkDraw() {
|
||||
if (CC_UNLIKELY(Properties::skpCaptureEnabled)) {
|
||||
mNode.markDrawEnd(mCanvas);
|
||||
}
|
||||
}
|
||||
private:
|
||||
SkCanvas& mCanvas;
|
||||
RenderNode& mNode;
|
||||
};
|
||||
|
||||
void RenderNodeDrawable::forceDraw(SkCanvas* canvas) {
|
||||
RenderNode* renderNode = mRenderNode.get();
|
||||
if (CC_UNLIKELY(Properties::skpCaptureEnabled)) {
|
||||
SkRect dimensions = SkRect::MakeWH(renderNode->getWidth(), renderNode->getHeight());
|
||||
canvas->drawAnnotation(dimensions, renderNode->getName(), nullptr);
|
||||
}
|
||||
MarkDraw _marker{*canvas, *renderNode};
|
||||
|
||||
// We only respect the nothingToDraw check when we are composing a layer. This
|
||||
// ensures that we paint the layer even if it is not currently visible in the
|
||||
|
||||
Reference in New Issue
Block a user