Loading libs/hwui/RenderNode.cpp +22 −16 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "RecordedOp.h" #include "TreeInfo.h" #include "utils/MathUtils.h" #include "utils/StringUtils.h" #include "utils/TraceUtils.h" #include "VectorDrawable.h" #include "renderstate/RenderState.h" Loading Loading @@ -68,31 +69,36 @@ void RenderNode::setStagingDisplayList(DisplayList* displayList, TreeObserver* o * This function is a simplified version of replay(), where we simply retrieve and log the * display list. This function should remain in sync with the replay() function. */ void RenderNode::output(uint32_t level, const char* label) { ALOGD("%s (%s %p%s%s%s%s%s)", label, getName(), this, (MathUtils::isZero(properties().getAlpha()) ? ", zero alpha" : ""), (properties().hasShadow() ? ", casting shadow" : ""), (isRenderable() ? "" : ", empty"), (properties().getProjectBackwards() ? ", projected" : ""), (mLayer != nullptr ? ", on HW Layer" : "")); properties().debugOutputProperties(level + 1); void RenderNode::output() { LogcatStream strout; strout << "Root"; output(strout, 0); } void RenderNode::output(std::ostream& output, uint32_t level) { output << " (" << getName() << " " << this << (MathUtils::isZero(properties().getAlpha()) ? ", zero alpha" : "") << (properties().hasShadow() ? ", casting shadow" : "") << (isRenderable() ? "" : ", empty") << (properties().getProjectBackwards() ? ", projected" : "") << (mLayer != nullptr ? ", on HW Layer" : "") << ")" << std::endl; properties().debugOutputProperties(output, level + 1); if (mDisplayList) { for (auto&& op : mDisplayList->getOps()) { std::stringstream strout; OpDumper::dump(*op, strout, level + 1); OpDumper::dump(*op, output, level + 1); if (op->opId == RecordedOpId::RenderNodeOp) { auto rnOp = reinterpret_cast<const RenderNodeOp*>(op); rnOp->renderNode->output(level + 1, strout.str().c_str()); rnOp->renderNode->output(output, level + 1); } else { ALOGD("%s", strout.str().c_str()); output << std::endl; } } } ALOGD("%*s/RenderNode(%s %p)", level * 2, "", getName(), this); output << std::string(level * 2, ' ') << "/RenderNode(" << getName() << " " << this << ")"; output << std::endl; } void RenderNode::copyTo(proto::RenderNode *pnode) { Loading libs/hwui/RenderNode.h +2 −1 Original line number Diff line number Diff line Loading @@ -102,7 +102,7 @@ public: void computeOrdering(); ANDROID_API void output(uint32_t level = 0, const char* label = "Root"); ANDROID_API void output(); ANDROID_API int getDebugSize(); void copyTo(proto::RenderNode* node); Loading Loading @@ -247,6 +247,7 @@ private: void incParentRefCount() { mParentCount++; } void decParentRefCount(TreeObserver* observer, TreeInfo* info = nullptr); void output(std::ostream& output, uint32_t level); String8 mName; sp<VirtualLightRefBase> mUserContext; Loading libs/hwui/RenderProperties.cpp +41 −28 Original line number Diff line number Diff line Loading @@ -99,26 +99,34 @@ RenderProperties& RenderProperties::operator=(const RenderProperties& other) { return *this; } void RenderProperties::debugOutputProperties(const int level) const { if (mPrimitiveFields.mLeft != 0 || mPrimitiveFields.mTop != 0) { ALOGD("%*s(Translate (left, top) %d, %d)", level * 2, "", mPrimitiveFields.mLeft, mPrimitiveFields.mTop); static void dumpMatrix(std::ostream& output, std::string& indent, const char* label, SkMatrix* matrix) { if (matrix) { output << indent << "(" << label << " " << matrix << ": "; output << std::fixed << std::setprecision(2); output << "[" << matrix->get(0) << " "<< matrix->get(1) << " " << matrix->get(2) << "]"; output << " [" << matrix->get(3) << " "<< matrix->get(4) << " " << matrix->get(5) << "]"; output << " [" << matrix->get(6) << " "<< matrix->get(7) << " " << matrix->get(8) << "]"; output << ")" << std::endl; } if (mStaticMatrix) { ALOGD("%*s(ConcatMatrix (static) %p: " SK_MATRIX_STRING ")", level * 2, "", mStaticMatrix, SK_MATRIX_ARGS(mStaticMatrix)); } if (mAnimationMatrix) { ALOGD("%*s(ConcatMatrix (animation) %p: " SK_MATRIX_STRING ")", level * 2, "", mAnimationMatrix, SK_MATRIX_ARGS(mAnimationMatrix)); void RenderProperties::debugOutputProperties(std::ostream& output, const int level) const { auto indent = std::string(level * 2, ' '); if (mPrimitiveFields.mLeft != 0 || mPrimitiveFields.mTop != 0) { output << indent << "(Translate (left, top) " << mPrimitiveFields.mLeft << ", " << mPrimitiveFields.mTop << ")" << std::endl; } dumpMatrix(output, indent, "ConcatMatrix (static)", mStaticMatrix); dumpMatrix(output, indent, "ConcatMatrix (animation)", mAnimationMatrix); output << std::fixed << std::setprecision(2); if (hasTransformMatrix()) { if (isTransformTranslateOnly()) { ALOGD("%*s(Translate %.2f, %.2f, %.2f)", level * 2, "", getTranslationX(), getTranslationY(), getZ()); output << indent << "(Translate " << getTranslationX() << ", " << getTranslationY() << ", " << getZ() << ")" << std::endl; } else { ALOGD("%*s(ConcatMatrix %p: " SK_MATRIX_STRING ")", level * 2, "", mComputedFields.mTransformMatrix, SK_MATRIX_ARGS(mComputedFields.mTransformMatrix)); dumpMatrix(output, indent, "ConcatMatrix ", mComputedFields.mTransformMatrix); } } Loading @@ -132,7 +140,7 @@ void RenderProperties::debugOutputProperties(const int level) const { if (CC_LIKELY(isLayer || !getHasOverlappingRendering())) { // simply scale rendering content's alpha ALOGD("%*s(ScaleAlpha %.2f)", level * 2, "", mPrimitiveFields.mAlpha); output << indent << "(ScaleAlpha " << mPrimitiveFields.mAlpha << ")" << std::endl; } else { // savelayeralpha to create an offscreen buffer to apply alpha Rect layerBounds(0, 0, getWidth(), getHeight()); Loading @@ -140,35 +148,40 @@ void RenderProperties::debugOutputProperties(const int level) const { getClippingRectForFlags(clipFlags, &layerBounds); clipFlags = 0; // all clipping done by savelayer } ALOGD("%*s(SaveLayerAlpha %d, %d, %d, %d, %d, 0x%x)", level * 2, "", (int)layerBounds.left, (int)layerBounds.top, (int)layerBounds.right, (int)layerBounds.bottom, (int)(mPrimitiveFields.mAlpha * 255), SaveFlags::HasAlphaLayer | SaveFlags::ClipToLayer); output << indent << "(SaveLayerAlpha " << (int)layerBounds.left << ", " << (int)layerBounds.top << ", " << (int)layerBounds.right << ", " << (int)layerBounds.bottom << ", " << (int)(mPrimitiveFields.mAlpha * 255) << ", 0x" << std::hex << (SaveFlags::HasAlphaLayer | SaveFlags::ClipToLayer) << ")" << std::dec << std::endl; } } if (clipFlags) { Rect clipRect; getClippingRectForFlags(clipFlags, &clipRect); ALOGD("%*s(ClipRect %d, %d, %d, %d)", level * 2, "", (int)clipRect.left, (int)clipRect.top, (int)clipRect.right, (int)clipRect.bottom); output << indent << "(ClipRect " << (int)clipRect.left << ", " << (int)clipRect.top << ", " << (int)clipRect.right << ", " << (int)clipRect.bottom << ")" << std::endl; } if (getRevealClip().willClip()) { Rect bounds; getRevealClip().getBounds(&bounds); ALOGD("%*s(Clip to reveal clip with bounds %.2f %.2f %.2f %.2f)", level * 2, "", RECT_ARGS(bounds)); output << indent << "(Clip to reveal clip with bounds " << bounds.left << ", " << bounds.top << ", " << bounds.right << ", " << bounds.bottom << ")" << std::endl; } auto& outline = mPrimitiveFields.mOutline; if (outline.getShouldClip()) { if (outline.isEmpty()) { ALOGD("%*s(Clip to empty outline)", level * 2, ""); output << indent << "(Clip to empty outline)"; } else if (outline.willClip()) { ALOGD("%*s(Clip to outline with bounds %.2f %.2f %.2f %.2f)", level * 2, "", RECT_ARGS(outline.getBounds())); const Rect& bounds = outline.getBounds(); output << indent << "(Clip to outline with bounds " << bounds.left << ", " << bounds.top << ", " << bounds.right << ", " << bounds.bottom << ")" << std::endl; } } } Loading libs/hwui/RenderProperties.h +2 −1 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ #include <cutils/compiler.h> #include <androidfw/ResourceTypes.h> #include <utils/Log.h> #include <ostream> class SkBitmap; class SkColorFilter; Loading Loading @@ -574,7 +575,7 @@ public: return mPrimitiveFields.mProjectBackwards; } void debugOutputProperties(const int level) const; void debugOutputProperties(std::ostream& output, const int level) const; void updateMatrix(); Loading libs/hwui/utils/StringUtils.h +22 −2 Original line number Diff line number Diff line Loading @@ -16,10 +16,14 @@ #ifndef STRING_UTILS_H #define STRING_UTILS_H #include <iomanip> #include <iostream> #include <ostream> #include <sstream> #include <string> #include <unordered_set> #include <ostream> #include <iomanip> #include <utils/Log.h> namespace android { namespace uirenderer { Loading Loading @@ -51,6 +55,22 @@ struct SizePrinter { } }; class LogcatStream: public std::ostream { class LogcatStreamBuf: public std::stringbuf { virtual int sync() { ALOGD("%s", str().c_str()); str(""); return 0; } }; LogcatStreamBuf buffer; public: LogcatStream() :std::ostream(&buffer) { } }; } /* namespace uirenderer */ } /* namespace android */ Loading Loading
libs/hwui/RenderNode.cpp +22 −16 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "RecordedOp.h" #include "TreeInfo.h" #include "utils/MathUtils.h" #include "utils/StringUtils.h" #include "utils/TraceUtils.h" #include "VectorDrawable.h" #include "renderstate/RenderState.h" Loading Loading @@ -68,31 +69,36 @@ void RenderNode::setStagingDisplayList(DisplayList* displayList, TreeObserver* o * This function is a simplified version of replay(), where we simply retrieve and log the * display list. This function should remain in sync with the replay() function. */ void RenderNode::output(uint32_t level, const char* label) { ALOGD("%s (%s %p%s%s%s%s%s)", label, getName(), this, (MathUtils::isZero(properties().getAlpha()) ? ", zero alpha" : ""), (properties().hasShadow() ? ", casting shadow" : ""), (isRenderable() ? "" : ", empty"), (properties().getProjectBackwards() ? ", projected" : ""), (mLayer != nullptr ? ", on HW Layer" : "")); properties().debugOutputProperties(level + 1); void RenderNode::output() { LogcatStream strout; strout << "Root"; output(strout, 0); } void RenderNode::output(std::ostream& output, uint32_t level) { output << " (" << getName() << " " << this << (MathUtils::isZero(properties().getAlpha()) ? ", zero alpha" : "") << (properties().hasShadow() ? ", casting shadow" : "") << (isRenderable() ? "" : ", empty") << (properties().getProjectBackwards() ? ", projected" : "") << (mLayer != nullptr ? ", on HW Layer" : "") << ")" << std::endl; properties().debugOutputProperties(output, level + 1); if (mDisplayList) { for (auto&& op : mDisplayList->getOps()) { std::stringstream strout; OpDumper::dump(*op, strout, level + 1); OpDumper::dump(*op, output, level + 1); if (op->opId == RecordedOpId::RenderNodeOp) { auto rnOp = reinterpret_cast<const RenderNodeOp*>(op); rnOp->renderNode->output(level + 1, strout.str().c_str()); rnOp->renderNode->output(output, level + 1); } else { ALOGD("%s", strout.str().c_str()); output << std::endl; } } } ALOGD("%*s/RenderNode(%s %p)", level * 2, "", getName(), this); output << std::string(level * 2, ' ') << "/RenderNode(" << getName() << " " << this << ")"; output << std::endl; } void RenderNode::copyTo(proto::RenderNode *pnode) { Loading
libs/hwui/RenderNode.h +2 −1 Original line number Diff line number Diff line Loading @@ -102,7 +102,7 @@ public: void computeOrdering(); ANDROID_API void output(uint32_t level = 0, const char* label = "Root"); ANDROID_API void output(); ANDROID_API int getDebugSize(); void copyTo(proto::RenderNode* node); Loading Loading @@ -247,6 +247,7 @@ private: void incParentRefCount() { mParentCount++; } void decParentRefCount(TreeObserver* observer, TreeInfo* info = nullptr); void output(std::ostream& output, uint32_t level); String8 mName; sp<VirtualLightRefBase> mUserContext; Loading
libs/hwui/RenderProperties.cpp +41 −28 Original line number Diff line number Diff line Loading @@ -99,26 +99,34 @@ RenderProperties& RenderProperties::operator=(const RenderProperties& other) { return *this; } void RenderProperties::debugOutputProperties(const int level) const { if (mPrimitiveFields.mLeft != 0 || mPrimitiveFields.mTop != 0) { ALOGD("%*s(Translate (left, top) %d, %d)", level * 2, "", mPrimitiveFields.mLeft, mPrimitiveFields.mTop); static void dumpMatrix(std::ostream& output, std::string& indent, const char* label, SkMatrix* matrix) { if (matrix) { output << indent << "(" << label << " " << matrix << ": "; output << std::fixed << std::setprecision(2); output << "[" << matrix->get(0) << " "<< matrix->get(1) << " " << matrix->get(2) << "]"; output << " [" << matrix->get(3) << " "<< matrix->get(4) << " " << matrix->get(5) << "]"; output << " [" << matrix->get(6) << " "<< matrix->get(7) << " " << matrix->get(8) << "]"; output << ")" << std::endl; } if (mStaticMatrix) { ALOGD("%*s(ConcatMatrix (static) %p: " SK_MATRIX_STRING ")", level * 2, "", mStaticMatrix, SK_MATRIX_ARGS(mStaticMatrix)); } if (mAnimationMatrix) { ALOGD("%*s(ConcatMatrix (animation) %p: " SK_MATRIX_STRING ")", level * 2, "", mAnimationMatrix, SK_MATRIX_ARGS(mAnimationMatrix)); void RenderProperties::debugOutputProperties(std::ostream& output, const int level) const { auto indent = std::string(level * 2, ' '); if (mPrimitiveFields.mLeft != 0 || mPrimitiveFields.mTop != 0) { output << indent << "(Translate (left, top) " << mPrimitiveFields.mLeft << ", " << mPrimitiveFields.mTop << ")" << std::endl; } dumpMatrix(output, indent, "ConcatMatrix (static)", mStaticMatrix); dumpMatrix(output, indent, "ConcatMatrix (animation)", mAnimationMatrix); output << std::fixed << std::setprecision(2); if (hasTransformMatrix()) { if (isTransformTranslateOnly()) { ALOGD("%*s(Translate %.2f, %.2f, %.2f)", level * 2, "", getTranslationX(), getTranslationY(), getZ()); output << indent << "(Translate " << getTranslationX() << ", " << getTranslationY() << ", " << getZ() << ")" << std::endl; } else { ALOGD("%*s(ConcatMatrix %p: " SK_MATRIX_STRING ")", level * 2, "", mComputedFields.mTransformMatrix, SK_MATRIX_ARGS(mComputedFields.mTransformMatrix)); dumpMatrix(output, indent, "ConcatMatrix ", mComputedFields.mTransformMatrix); } } Loading @@ -132,7 +140,7 @@ void RenderProperties::debugOutputProperties(const int level) const { if (CC_LIKELY(isLayer || !getHasOverlappingRendering())) { // simply scale rendering content's alpha ALOGD("%*s(ScaleAlpha %.2f)", level * 2, "", mPrimitiveFields.mAlpha); output << indent << "(ScaleAlpha " << mPrimitiveFields.mAlpha << ")" << std::endl; } else { // savelayeralpha to create an offscreen buffer to apply alpha Rect layerBounds(0, 0, getWidth(), getHeight()); Loading @@ -140,35 +148,40 @@ void RenderProperties::debugOutputProperties(const int level) const { getClippingRectForFlags(clipFlags, &layerBounds); clipFlags = 0; // all clipping done by savelayer } ALOGD("%*s(SaveLayerAlpha %d, %d, %d, %d, %d, 0x%x)", level * 2, "", (int)layerBounds.left, (int)layerBounds.top, (int)layerBounds.right, (int)layerBounds.bottom, (int)(mPrimitiveFields.mAlpha * 255), SaveFlags::HasAlphaLayer | SaveFlags::ClipToLayer); output << indent << "(SaveLayerAlpha " << (int)layerBounds.left << ", " << (int)layerBounds.top << ", " << (int)layerBounds.right << ", " << (int)layerBounds.bottom << ", " << (int)(mPrimitiveFields.mAlpha * 255) << ", 0x" << std::hex << (SaveFlags::HasAlphaLayer | SaveFlags::ClipToLayer) << ")" << std::dec << std::endl; } } if (clipFlags) { Rect clipRect; getClippingRectForFlags(clipFlags, &clipRect); ALOGD("%*s(ClipRect %d, %d, %d, %d)", level * 2, "", (int)clipRect.left, (int)clipRect.top, (int)clipRect.right, (int)clipRect.bottom); output << indent << "(ClipRect " << (int)clipRect.left << ", " << (int)clipRect.top << ", " << (int)clipRect.right << ", " << (int)clipRect.bottom << ")" << std::endl; } if (getRevealClip().willClip()) { Rect bounds; getRevealClip().getBounds(&bounds); ALOGD("%*s(Clip to reveal clip with bounds %.2f %.2f %.2f %.2f)", level * 2, "", RECT_ARGS(bounds)); output << indent << "(Clip to reveal clip with bounds " << bounds.left << ", " << bounds.top << ", " << bounds.right << ", " << bounds.bottom << ")" << std::endl; } auto& outline = mPrimitiveFields.mOutline; if (outline.getShouldClip()) { if (outline.isEmpty()) { ALOGD("%*s(Clip to empty outline)", level * 2, ""); output << indent << "(Clip to empty outline)"; } else if (outline.willClip()) { ALOGD("%*s(Clip to outline with bounds %.2f %.2f %.2f %.2f)", level * 2, "", RECT_ARGS(outline.getBounds())); const Rect& bounds = outline.getBounds(); output << indent << "(Clip to outline with bounds " << bounds.left << ", " << bounds.top << ", " << bounds.right << ", " << bounds.bottom << ")" << std::endl; } } } Loading
libs/hwui/RenderProperties.h +2 −1 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ #include <cutils/compiler.h> #include <androidfw/ResourceTypes.h> #include <utils/Log.h> #include <ostream> class SkBitmap; class SkColorFilter; Loading Loading @@ -574,7 +575,7 @@ public: return mPrimitiveFields.mProjectBackwards; } void debugOutputProperties(const int level) const; void debugOutputProperties(std::ostream& output, const int level) const; void updateMatrix(); Loading
libs/hwui/utils/StringUtils.h +22 −2 Original line number Diff line number Diff line Loading @@ -16,10 +16,14 @@ #ifndef STRING_UTILS_H #define STRING_UTILS_H #include <iomanip> #include <iostream> #include <ostream> #include <sstream> #include <string> #include <unordered_set> #include <ostream> #include <iomanip> #include <utils/Log.h> namespace android { namespace uirenderer { Loading Loading @@ -51,6 +55,22 @@ struct SizePrinter { } }; class LogcatStream: public std::ostream { class LogcatStreamBuf: public std::stringbuf { virtual int sync() { ALOGD("%s", str().c_str()); str(""); return 0; } }; LogcatStreamBuf buffer; public: LogcatStream() :std::ostream(&buffer) { } }; } /* namespace uirenderer */ } /* namespace android */ Loading