From 3b4510cd774d1a9e48b4758e95b02e7b32853607 Mon Sep 17 00:00:00 2001 From: John Reck Date: Thu, 27 Sep 2018 17:39:45 -0700 Subject: [PATCH] Auto-dark NinePatches & launcher Support palette for ninepatches (fixes popupwindow) Crude heuristic tweak to treat any RenderNode that fully contains other nodes as background nodes. Test: all apps is now readable, and so is chrome's menu Change-Id: I9926973c0be1dbf0088fa2d61e4ee2a414b19a97 --- libs/hwui/RecordingCanvas.cpp | 102 ++++++++++++------ libs/hwui/RecordingCanvas.h | 8 +- libs/hwui/RenderNode.cpp | 52 ++++++--- libs/hwui/RenderNode.h | 1 + .../pipeline/skia/SkiaRecordingCanvas.cpp | 5 +- 5 files changed, 114 insertions(+), 54 deletions(-) diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp index c30af842ebbbc..f928de9b92a60 100644 --- a/libs/hwui/RecordingCanvas.cpp +++ b/libs/hwui/RecordingCanvas.cpp @@ -23,6 +23,7 @@ #include "SkDrawShadowInfo.h" #include "SkImage.h" #include "SkImageFilter.h" +#include "SkLatticeIter.h" #include "SkMath.h" #include "SkPicture.h" #include "SkRSXform.h" @@ -280,7 +281,8 @@ struct DrawPicture final : Op { struct DrawImage final : Op { static const auto kType = Type::DrawImage; - DrawImage(sk_sp&& image, SkScalar x, SkScalar y, const SkPaint* paint, BitmapPalette palette) + DrawImage(sk_sp&& image, SkScalar x, SkScalar y, const SkPaint* paint, + BitmapPalette palette) : image(std::move(image)), x(x), y(y), palette(palette) { if (paint) { this->paint = *paint; @@ -312,7 +314,8 @@ struct DrawImageNine final : Op { struct DrawImageRect final : Op { static const auto kType = Type::DrawImageRect; DrawImageRect(sk_sp&& image, const SkRect* src, const SkRect& dst, - const SkPaint* paint, SkCanvas::SrcRectConstraint constraint, BitmapPalette palette) + const SkPaint* paint, SkCanvas::SrcRectConstraint constraint, + BitmapPalette palette) : image(std::move(image)), dst(dst), constraint(constraint), palette(palette) { this->src = src ? *src : SkRect::MakeIWH(this->image->width(), this->image->height()); if (paint) { @@ -331,8 +334,14 @@ struct DrawImageRect final : Op { struct DrawImageLattice final : Op { static const auto kType = Type::DrawImageLattice; DrawImageLattice(sk_sp&& image, int xs, int ys, int fs, const SkIRect& src, - const SkRect& dst, const SkPaint* paint) - : image(std::move(image)), xs(xs), ys(ys), fs(fs), src(src), dst(dst) { + const SkRect& dst, const SkPaint* paint, BitmapPalette palette) + : image(std::move(image)) + , xs(xs) + , ys(ys) + , fs(fs) + , src(src) + , dst(dst) + , palette(palette) { if (paint) { this->paint = *paint; } @@ -342,6 +351,7 @@ struct DrawImageLattice final : Op { SkIRect src; SkRect dst; SkPaint paint; + BitmapPalette palette; void draw(SkCanvas* c, const SkMatrix&) const { auto xdivs = pod(this, 0), ydivs = pod(this, xs * sizeof(int)); auto colors = (0 == fs) ? nullptr : pod(this, (xs + ys) * sizeof(int)); @@ -511,16 +521,13 @@ struct DrawVectorDrawable final : Op { tree->getPaintFor(&paint, tree->stagingProperties()); } - void draw(SkCanvas* canvas, const SkMatrix&) const { - mRoot->draw(canvas, mBounds, paint); - } + void draw(SkCanvas* canvas, const SkMatrix&) const { mRoot->draw(canvas, mBounds, paint); } sp mRoot; SkRect mBounds; SkPaint paint; BitmapPalette palette; }; - } template @@ -647,14 +654,15 @@ void DisplayListData::drawImageRect(sk_sp image, const SkRect* sr this->push(0, std::move(image), src, dst, paint, constraint, palette); } void DisplayListData::drawImageLattice(sk_sp image, const SkCanvas::Lattice& lattice, - const SkRect& dst, const SkPaint* paint) { + const SkRect& dst, const SkPaint* paint, + BitmapPalette palette) { int xs = lattice.fXCount, ys = lattice.fYCount; int fs = lattice.fRectTypes ? (xs + 1) * (ys + 1) : 0; size_t bytes = (xs + ys) * sizeof(int) + fs * sizeof(SkCanvas::Lattice::RectType) + fs * sizeof(SkColor); SkASSERT(lattice.fBounds); void* pod = this->push(bytes, std::move(image), xs, ys, fs, *lattice.fBounds, - dst, paint); + dst, paint, palette); copy_v(pod, lattice.fXDivs, xs, lattice.fYDivs, ys, lattice.fColors, fs, lattice.fRectTypes, fs); } @@ -779,22 +787,26 @@ constexpr bool has_palette = std::experimental::is_detected_v constexpr color_transform_fn colorTransformForOp() { - if constexpr(has_paint && has_palette) { - // It's a bitmap - return [](const void* opRaw, ColorTransform transform) { - // TODO: We should be const. Or not. Or just use a different map - // Unclear, but this is the quick fix - const T* op = reinterpret_cast(opRaw); - transformPaint(transform, const_cast(&(op->paint)), op->palette); - }; - } else if constexpr(has_paint) { - return [](const void* opRaw, ColorTransform transform) { - // TODO: We should be const. Or not. Or just use a different map - // Unclear, but this is the quick fix - const T* op = reinterpret_cast(opRaw); - transformPaint(transform, const_cast(&(op->paint))); - }; - } else { + if + constexpr(has_paint && has_palette) { + // It's a bitmap + return [](const void* opRaw, ColorTransform transform) { + // TODO: We should be const. Or not. Or just use a different map + // Unclear, but this is the quick fix + const T* op = reinterpret_cast(opRaw); + transformPaint(transform, const_cast(&(op->paint)), op->palette); + }; + } + else if + constexpr(has_paint) { + return [](const void* opRaw, ColorTransform transform) { + // TODO: We should be const. Or not. Or just use a different map + // Unclear, but this is the quick fix + const T* op = reinterpret_cast(opRaw); + transformPaint(transform, const_cast(&(op->paint))); + }; + } + else { return nullptr; } } @@ -931,11 +943,12 @@ void RecordingCanvas::onDrawBitmapNine(const SkBitmap& bm, const SkIRect& center } void RecordingCanvas::onDrawBitmapRect(const SkBitmap& bm, const SkRect* src, const SkRect& dst, const SkPaint* paint, SrcRectConstraint constraint) { - fDL->drawImageRect(SkImage::MakeFromBitmap(bm), src, dst, paint, constraint, BitmapPalette::Unknown); + fDL->drawImageRect(SkImage::MakeFromBitmap(bm), src, dst, paint, constraint, + BitmapPalette::Unknown); } void RecordingCanvas::onDrawBitmapLattice(const SkBitmap& bm, const SkCanvas::Lattice& lattice, const SkRect& dst, const SkPaint* paint) { - fDL->drawImageLattice(SkImage::MakeFromBitmap(bm), lattice, dst, paint); + fDL->drawImageLattice(SkImage::MakeFromBitmap(bm), lattice, dst, paint, BitmapPalette::Unknown); } void RecordingCanvas::drawImage(const sk_sp& image, SkScalar x, SkScalar y, @@ -943,11 +956,34 @@ void RecordingCanvas::drawImage(const sk_sp& image, SkScalar x, SkScala fDL->drawImage(image, x, y, paint, palette); } -void RecordingCanvas::drawImageRect(const sk_sp& image, const SkRect& src, const SkRect& dst, - const SkPaint* paint, SrcRectConstraint constraint, BitmapPalette palette) { +void RecordingCanvas::drawImageRect(const sk_sp& image, const SkRect& src, + const SkRect& dst, const SkPaint* paint, + SrcRectConstraint constraint, BitmapPalette palette) { fDL->drawImageRect(image, &src, dst, paint, constraint, palette); } +void RecordingCanvas::drawImageLattice(const sk_sp& image, const Lattice& lattice, + const SkRect& dst, const SkPaint* paint, + BitmapPalette palette) { + if (!image || dst.isEmpty()) { + return; + } + + SkIRect bounds; + Lattice latticePlusBounds = lattice; + if (!latticePlusBounds.fBounds) { + bounds = SkIRect::MakeWH(image->width(), image->height()); + latticePlusBounds.fBounds = &bounds; + } + + if (SkLatticeIter::Valid(image->width(), image->height(), latticePlusBounds)) { + fDL->drawImageLattice(image, latticePlusBounds, dst, paint, palette); + } else { + fDL->drawImageRect(image, nullptr, dst, paint, SrcRectConstraint::kFast_SrcRectConstraint, + palette); + } +} + void RecordingCanvas::onDrawImage(const SkImage* img, SkScalar x, SkScalar y, const SkPaint* paint) { fDL->drawImage(sk_ref_sp(img), x, y, paint, BitmapPalette::Unknown); @@ -962,7 +998,7 @@ void RecordingCanvas::onDrawImageRect(const SkImage* img, const SkRect* src, con } void RecordingCanvas::onDrawImageLattice(const SkImage* img, const SkCanvas::Lattice& lattice, const SkRect& dst, const SkPaint* paint) { - fDL->drawImageLattice(sk_ref_sp(img), lattice, dst, paint); + fDL->drawImageLattice(sk_ref_sp(img), lattice, dst, paint, BitmapPalette::Unknown); } void RecordingCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], @@ -975,8 +1011,8 @@ void RecordingCanvas::onDrawPoints(SkCanvas::PointMode mode, size_t count, const fDL->drawPoints(mode, count, pts, paint); } void RecordingCanvas::onDrawVerticesObject(const SkVertices* vertices, - const SkVertices::Bone bones[], int boneCount, - SkBlendMode mode, const SkPaint& paint) { + const SkVertices::Bone bones[], int boneCount, + SkBlendMode mode, const SkPaint& paint) { fDL->drawVertices(vertices, bones, boneCount, mode, paint); } void RecordingCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xforms[], diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h index 80c80ca46515c..099e0be433ea9 100644 --- a/libs/hwui/RecordingCanvas.h +++ b/libs/hwui/RecordingCanvas.h @@ -110,7 +110,7 @@ private: void drawImageRect(sk_sp, const SkRect*, const SkRect&, const SkPaint*, SkCanvas::SrcRectConstraint, BitmapPalette palette); void drawImageLattice(sk_sp, const SkCanvas::Lattice&, const SkRect&, - const SkPaint*); + const SkPaint*, BitmapPalette); void drawPatch(const SkPoint[12], const SkColor[4], const SkPoint[4], SkBlendMode, const SkPaint&); @@ -185,11 +185,13 @@ public: void onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint*, SrcRectConstraint) override; - void drawImage(const sk_sp& image, SkScalar left, SkScalar top, - const SkPaint* paint, BitmapPalette pallete); + void drawImage(const sk_sp& image, SkScalar left, SkScalar top, const SkPaint* paint, + BitmapPalette pallete); void drawImageRect(const sk_sp& image, const SkRect& src, const SkRect& dst, const SkPaint* paint, SrcRectConstraint constraint, BitmapPalette palette); + void drawImageLattice(const sk_sp& image, const Lattice& lattice, const SkRect& dst, + const SkPaint* paint, BitmapPalette palette); void onDrawImage(const SkImage*, SkScalar, SkScalar, const SkPaint*) override; void onDrawImageLattice(const SkImage*, const Lattice&, const SkRect&, const SkPaint*) override; diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index d9a7cc3a575f7..d2a8f02cc6a7b 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -282,25 +282,45 @@ void RenderNode::syncDisplayList(TreeObserver& observer, TreeInfo* info) { mStagingDisplayList = nullptr; if (mDisplayList) { mDisplayList->syncContents(); + handleForceDark(info); + } +} - if (CC_UNLIKELY(info && !info->disableForceDark)) { - auto usage = usageHint(); - if (mDisplayList->hasText()) { - usage = UsageHint::Foreground; - } - if (usage == UsageHint::Unknown) { - if (mDisplayList->mChildNodes.size() > 1) { - usage = UsageHint::Background; - } else if (mDisplayList->mChildNodes.size() == 1 && - mDisplayList->mChildNodes.front().getRenderNode()->usageHint() != - UsageHint::Background) { - usage = UsageHint::Background; - } - } - mDisplayList->mDisplayList.applyColorTransform( - usage == UsageHint::Background ? ColorTransform::Dark : ColorTransform::Light); +void RenderNode::handleForceDark(android::uirenderer::TreeInfo *info) { + if (CC_LIKELY(!info || info->disableForceDark)) { + return; + } + auto usage = usageHint(); + const auto& children = mDisplayList->mChildNodes; + if (mDisplayList->hasText()) { + usage = UsageHint::Foreground; + } + if (usage == UsageHint::Unknown) { + if (children.size() > 1) { + usage = UsageHint::Background; + } else if (children.size() == 1 && + children.front().getRenderNode()->usageHint() != + UsageHint::Background) { + usage = UsageHint::Background; } } + if (children.size() > 1) { + // Crude overlap check + SkRect drawn = SkRect::MakeEmpty(); + for (auto iter = children.rbegin(); iter != children.rend(); ++iter) { + const auto& child = iter->getRenderNode(); + // We use stagingProperties here because we haven't yet sync'd the children + SkRect bounds = SkRect::MakeXYWH(child->stagingProperties().getX(), child->stagingProperties().getY(), + child->stagingProperties().getWidth(), child->stagingProperties().getHeight()); + if (bounds.contains(drawn)) { + // This contains everything drawn after it, so make it a background + child->setUsageHint(UsageHint::Background); + } + drawn.join(bounds); + } + } + mDisplayList->mDisplayList.applyColorTransform( + usage == UsageHint::Background ? ColorTransform::Dark : ColorTransform::Light); } void RenderNode::pushStagingDisplayListChanges(TreeObserver& observer, TreeInfo& info) { diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h index 211dd2db5cf8e..be0b46b1c45fd 100644 --- a/libs/hwui/RenderNode.h +++ b/libs/hwui/RenderNode.h @@ -220,6 +220,7 @@ private: void syncProperties(); void syncDisplayList(TreeObserver& observer, TreeInfo* info); + void handleForceDark(TreeInfo* info); void prepareTreeImpl(TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer); void pushStagingPropertiesChanges(TreeInfo& info); diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp index fac07d74dad49..3fa73a4dadda8 100644 --- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp +++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp @@ -245,8 +245,9 @@ void SkiaRecordingCanvas::drawNinePatch(Bitmap& bitmap, const Res_png_9patch& ch } sk_sp colorFilter; sk_sp image = bitmap.makeImage(&colorFilter); - mRecorder.drawImageLattice(image.get(), lattice, dst, - filterBitmap(std::move(filteredPaint), std::move(colorFilter))); + mRecorder.drawImageLattice(image, lattice, dst, + filterBitmap(std::move(filteredPaint), std::move(colorFilter)), + bitmap.palette()); if (!bitmap.isImmutable() && image.get() && !image->unique() && !dst.isEmpty()) { mDisplayList->mMutableImages.push_back(image.get()); }