Add a unique ID to rendernode

Bug: 120089776
Test: dump'd skp, verified ID present
Change-Id: I97a03804ebc53925e1b79db3dd616a728eff0bfa
This commit is contained in:
John Reck
2018-11-29 09:44:10 -08:00
parent 9a72ec33d7
commit f96b284dec
6 changed files with 90 additions and 5 deletions

View File

@@ -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();

View File

@@ -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) {

View File

@@ -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);
}

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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