Make auto-dark a bit better
Handles transform of basic bitmaps
Tweak to always treat text as foreground
Test: builds, poked around with force_dark
Change-Id: I733d39e05067438335da5a7eac06111f66f1228d
diff --git a/libs/hwui/CanvasTransform.cpp b/libs/hwui/CanvasTransform.cpp
index adcdc18..a03b317 100644
--- a/libs/hwui/CanvasTransform.cpp
+++ b/libs/hwui/CanvasTransform.cpp
@@ -28,6 +28,7 @@
#include <cmath>
#include <log/log.h>
+#include <SkHighContrastFilter.h>
namespace android::uirenderer {
@@ -113,4 +114,20 @@
return true;
}
+bool transformPaint(ColorTransform transform, SkPaint* paint, BitmapPalette palette) {
+ bool shouldInvert = false;
+ if (palette == BitmapPalette::Light && transform == ColorTransform::Dark) {
+ shouldInvert = true;
+ }
+ if (palette == BitmapPalette::Dark && transform == ColorTransform::Light) {
+ shouldInvert = true;
+ }
+ if (shouldInvert) {
+ SkHighContrastConfig config;
+ config.fInvertStyle = SkHighContrastConfig::InvertStyle::kInvertLightness;
+ paint->setColorFilter(SkHighContrastFilter::Make(config)->makeComposed(paint->refColorFilter()));
+ }
+ return shouldInvert;
+}
+
}; // namespace android::uirenderer
\ No newline at end of file
diff --git a/libs/hwui/CanvasTransform.h b/libs/hwui/CanvasTransform.h
index 32d9a05..e723d64 100644
--- a/libs/hwui/CanvasTransform.h
+++ b/libs/hwui/CanvasTransform.h
@@ -16,6 +16,8 @@
#pragma once
+#include "hwui/Bitmap.h"
+
#include <SkCanvas.h>
#include <SkPaintFilterCanvas.h>
@@ -26,6 +28,7 @@
enum class UsageHint {
Unknown = 0,
Background = 1,
+ Foreground = 2,
};
enum class ColorTransform {
@@ -37,4 +40,6 @@
// True if the paint was modified, false otherwise
bool transformPaint(ColorTransform transform, SkPaint* paint);
+bool transformPaint(ColorTransform transform, SkPaint* paint, BitmapPalette palette);
+
} // namespace android::uirenderer;
\ No newline at end of file
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 3eaff03..5f54c02 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -278,8 +278,8 @@
struct DrawImage final : Op {
static const auto kType = Type::DrawImage;
- DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y, const SkPaint* paint)
- : image(std::move(image)), x(x), y(y) {
+ DrawImage(sk_sp<const SkImage>&& 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;
}
@@ -287,6 +287,7 @@
sk_sp<const SkImage> image;
SkScalar x, y;
SkPaint paint;
+ BitmapPalette palette;
void draw(SkCanvas* c, const SkMatrix&) const { c->drawImage(image.get(), x, y, &paint); }
};
struct DrawImageNine final : Op {
@@ -309,8 +310,8 @@
struct DrawImageRect final : Op {
static const auto kType = Type::DrawImageRect;
DrawImageRect(sk_sp<const SkImage>&& image, const SkRect* src, const SkRect& dst,
- const SkPaint* paint, SkCanvas::SrcRectConstraint constraint)
- : image(std::move(image)), dst(dst), constraint(constraint) {
+ 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) {
this->paint = *paint;
@@ -320,6 +321,7 @@
SkRect src, dst;
SkPaint paint;
SkCanvas::SrcRectConstraint constraint;
+ BitmapPalette palette;
void draw(SkCanvas* c, const SkMatrix&) const {
c->drawImageRect(image.get(), src, dst, &paint, constraint);
}
@@ -609,8 +611,8 @@
this->push<DrawPicture>(0, picture, matrix, paint);
}
void DisplayListData::drawImage(sk_sp<const SkImage> image, SkScalar x, SkScalar y,
- const SkPaint* paint) {
- this->push<DrawImage>(0, std::move(image), x, y, paint);
+ const SkPaint* paint, BitmapPalette palette) {
+ this->push<DrawImage>(0, std::move(image), x, y, paint, palette);
}
void DisplayListData::drawImageNine(sk_sp<const SkImage> image, const SkIRect& center,
const SkRect& dst, const SkPaint* paint) {
@@ -618,8 +620,8 @@
}
void DisplayListData::drawImageRect(sk_sp<const SkImage> image, const SkRect* src,
const SkRect& dst, const SkPaint* paint,
- SkCanvas::SrcRectConstraint constraint) {
- this->push<DrawImageRect>(0, std::move(image), src, dst, paint, constraint);
+ SkCanvas::SrcRectConstraint constraint, BitmapPalette palette) {
+ this->push<DrawImageRect>(0, std::move(image), src, dst, paint, constraint, palette);
}
void DisplayListData::drawImageLattice(sk_sp<const SkImage> image, const SkCanvas::Lattice& lattice,
const SkRect& dst, const SkPaint* paint) {
@@ -638,28 +640,33 @@
const SkPaint& paint) {
void* pod = this->push<DrawText>(bytes, bytes, x, y, paint);
copy_v(pod, (const char*)text, bytes);
+ mHasText = true;
}
void DisplayListData::drawPosText(const void* text, size_t bytes, const SkPoint pos[],
const SkPaint& paint) {
int n = paint.countText(text, bytes);
void* pod = this->push<DrawPosText>(n * sizeof(SkPoint) + bytes, bytes, paint, n);
copy_v(pod, pos, n, (const char*)text, bytes);
+ mHasText = true;
}
void DisplayListData::drawPosTextH(const void* text, size_t bytes, const SkScalar xs[], SkScalar y,
const SkPaint& paint) {
int n = paint.countText(text, bytes);
void* pod = this->push<DrawPosTextH>(n * sizeof(SkScalar) + bytes, bytes, y, paint, n);
copy_v(pod, xs, n, (const char*)text, bytes);
+ mHasText = true;
}
void DisplayListData::drawTextRSXform(const void* text, size_t bytes, const SkRSXform xforms[],
const SkRect* cull, const SkPaint& paint) {
int n = paint.countText(text, bytes);
void* pod = this->push<DrawTextRSXform>(bytes + n * sizeof(SkRSXform), bytes, n, cull, paint);
copy_v(pod, xforms, n, (const char*)text, bytes);
+ mHasText = true;
}
void DisplayListData::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
const SkPaint& paint) {
this->push<DrawTextBlob>(0, blob, x, y, paint);
+ mHasText = true;
}
void DisplayListData::drawPatch(const SkPoint points[12], const SkColor colors[4],
@@ -733,20 +740,35 @@
}
template <class T>
-using has_paint_t = decltype(std::declval<T>().paint);
+using has_paint_helper = decltype(std::declval<T>().paint);
+
+template <class T>
+constexpr bool has_paint = std::experimental::is_detected_v<has_paint_helper, T>;
+
+template <class T>
+using has_palette_helper = decltype(std::declval<T>().palette);
+
+template <class T>
+constexpr bool has_palette = std::experimental::is_detected_v<has_palette_helper, T>;
template <class T>
constexpr color_transform_fn colorTransformForOp() {
- if
- constexpr(std::experimental::is_detected_v<has_paint_t, T>) {
- return [](const void* op, ColorTransform transform) {
- // TODO: We should be const. Or not. Or just use a different map
- // Unclear, but this is the quick fix
- transformPaint(transform,
- const_cast<SkPaint*>(&(reinterpret_cast<const T*>(op)->paint)));
- };
- }
- else {
+ if constexpr(has_paint<T> && has_palette<T>) {
+ // 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<const T*>(opRaw);
+ transformPaint(transform, const_cast<SkPaint*>(&(op->paint)), op->palette);
+ };
+ } else if constexpr(has_paint<T>) {
+ 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<const T*>(opRaw);
+ transformPaint(transform, const_cast<SkPaint*>(&(op->paint)));
+ };
+ } else {
return nullptr;
}
}
@@ -875,7 +897,7 @@
void RecordingCanvas::onDrawBitmap(const SkBitmap& bm, SkScalar x, SkScalar y,
const SkPaint* paint) {
- fDL->drawImage(SkImage::MakeFromBitmap(bm), x, y, paint);
+ fDL->drawImage(SkImage::MakeFromBitmap(bm), x, y, paint, BitmapPalette::Unknown);
}
void RecordingCanvas::onDrawBitmapNine(const SkBitmap& bm, const SkIRect& center, const SkRect& dst,
const SkPaint* paint) {
@@ -883,16 +905,26 @@
}
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);
+ 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);
}
+void RecordingCanvas::drawImage(const sk_sp<SkImage>& image, SkScalar x, SkScalar y,
+ const SkPaint* paint, BitmapPalette palette) {
+ fDL->drawImage(image, x, y, paint, palette);
+}
+
+void RecordingCanvas::drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
+ const SkPaint* paint, SrcRectConstraint constraint, BitmapPalette palette) {
+ fDL->drawImageRect(image, &src, dst, paint, constraint, palette);
+}
+
void RecordingCanvas::onDrawImage(const SkImage* img, SkScalar x, SkScalar y,
const SkPaint* paint) {
- fDL->drawImage(sk_ref_sp(img), x, y, paint);
+ fDL->drawImage(sk_ref_sp(img), x, y, paint, BitmapPalette::Unknown);
}
void RecordingCanvas::onDrawImageNine(const SkImage* img, const SkIRect& center, const SkRect& dst,
const SkPaint* paint) {
@@ -900,7 +932,7 @@
}
void RecordingCanvas::onDrawImageRect(const SkImage* img, const SkRect* src, const SkRect& dst,
const SkPaint* paint, SrcRectConstraint constraint) {
- fDL->drawImageRect(sk_ref_sp(img), src, dst, paint, constraint);
+ fDL->drawImageRect(sk_ref_sp(img), src, dst, paint, constraint, BitmapPalette::Unknown);
}
void RecordingCanvas::onDrawImageLattice(const SkImage* img, const SkCanvas::Lattice& lattice,
const SkRect& dst, const SkPaint* paint) {
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 32ce1d3..eecf51c 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -17,6 +17,7 @@
#pragma once
#include "CanvasTransform.h"
+#include "hwui/Bitmap.h"
#include "hwui/Canvas.h"
#include "utils/Macros.h"
#include "utils/TypeLogic.h"
@@ -53,6 +54,7 @@
class DisplayListData final {
public:
+ DisplayListData() : mHasText(false) {}
~DisplayListData();
void draw(SkCanvas* canvas) const;
@@ -62,6 +64,8 @@
void applyColorTransform(ColorTransform transform);
+ bool hasText() const { return mHasText; }
+
private:
friend class RecordingCanvas;
@@ -101,10 +105,10 @@
void drawTextRSXform(const void*, size_t, const SkRSXform[], const SkRect*, const SkPaint&);
void drawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&);
- void drawImage(sk_sp<const SkImage>, SkScalar, SkScalar, const SkPaint*);
+ void drawImage(sk_sp<const SkImage>, SkScalar, SkScalar, const SkPaint*, BitmapPalette palette);
void drawImageNine(sk_sp<const SkImage>, const SkIRect&, const SkRect&, const SkPaint*);
void drawImageRect(sk_sp<const SkImage>, const SkRect*, const SkRect&, const SkPaint*,
- SkCanvas::SrcRectConstraint);
+ SkCanvas::SrcRectConstraint, BitmapPalette palette);
void drawImageLattice(sk_sp<const SkImage>, const SkCanvas::Lattice&, const SkRect&,
const SkPaint*);
@@ -126,6 +130,8 @@
SkAutoTMalloc<uint8_t> fBytes;
size_t fUsed = 0;
size_t fReserved = 0;
+
+ bool mHasText : 1;
};
class RecordingCanvas final : public SkCanvasVirtualEnforcer<SkNoDrawCanvas> {
@@ -178,6 +184,12 @@
void onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint*,
SrcRectConstraint) override;
+ void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
+ const SkPaint* paint, BitmapPalette pallete);
+
+ void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
+ const SkPaint* paint, SrcRectConstraint constraint, BitmapPalette palette);
+
void onDrawImage(const SkImage*, SkScalar, SkScalar, const SkPaint*) override;
void onDrawImageLattice(const SkImage*, const Lattice&, const SkRect&, const SkPaint*) override;
void onDrawImageNine(const SkImage*, const SkIRect&, const SkRect&, const SkPaint*) override;
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index d5afb20..26e5cea 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -272,8 +272,12 @@
mStagingDisplayList = nullptr;
if (mDisplayList) {
mDisplayList->syncContents();
+
if (CC_UNLIKELY(Properties::forceDarkMode)) {
auto usage = usageHint();
+ if (mDisplayList->hasText()) {
+ usage = UsageHint::Foreground;
+ }
if (usage == UsageHint::Unknown) {
if (mDisplayList->mChildNodes.size() > 1) {
usage = UsageHint::Background;
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index 83b0c22..211dd2d 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -107,7 +107,7 @@
bool isRenderable() const { return mDisplayList && !mDisplayList->isEmpty(); }
bool hasProjectionReceiver() const {
- return mDisplayList && mDisplayList->projectionReceiveIndex >= 0;
+ return mDisplayList && mDisplayList->containsProjectionReceiver();
}
const char* getName() const { return mName.string(); }
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 440620a..6556a64 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -330,15 +330,6 @@
if (image->colorSpace() != nullptr && !image->colorSpace()->isSRGB()) {
*outputColorFilter = SkToSRGBColorFilter::Make(image->refColorSpace());
}
-
- // TODO: Move this to the canvas (or other?) layer where we have the target lightness
- // mode and can selectively do the right thing.
- // if (palette() != BitmapPalette::Unknown && uirenderer::Properties::forceDarkMode) {
- // SkHighContrastConfig config;
- // config.fInvertStyle = SkHighContrastConfig::InvertStyle::kInvertLightness;
- // *outputColorFilter =
- // SkHighContrastFilter::Make(config)->makeComposed(*outputColorFilter);
- // }
return image;
}
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
index 78b64b2..3890513 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
@@ -132,7 +132,6 @@
mChildFunctors.clear();
mChildNodes.clear();
- projectionReceiveIndex = -1;
allocator.~LinearAllocator();
new (&allocator) LinearAllocator();
}
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.h b/libs/hwui/pipeline/skia/SkiaDisplayList.h
index 4c78539..ac7bb7b 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.h
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.h
@@ -49,9 +49,6 @@
*/
class SkiaDisplayList {
public:
- // index of DisplayListOp restore, after which projected descendants should be drawn
- int projectionReceiveIndex = -1;
-
size_t getUsedSize() { return allocator.usedSize(); }
~SkiaDisplayList() {
@@ -96,6 +93,8 @@
*/
bool hasVectorDrawables() const { return !mVectorDrawables.empty(); }
+ bool hasText() const { return mDisplayList.hasText(); }
+
/**
* Attempts to reset and reuse this DisplayList.
*
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index 3c281e78..3042006e 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -113,8 +113,6 @@
// use staging property, since recording on UI thread
if (renderNode->stagingProperties().isProjectionReceiver()) {
mDisplayList->mProjectionReceiver = &renderNodeDrawable;
- // set projectionReceiveIndex so that RenderNode.hasProjectionReceiver returns true
- mDisplayList->projectionReceiveIndex = mDisplayList->mChildNodes.size() - 1;
}
}
@@ -196,7 +194,7 @@
void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) {
sk_sp<SkColorFilter> colorFilter;
sk_sp<SkImage> image = bitmap.makeImage(&colorFilter);
- mRecorder.drawImage(image, left, top, filterBitmap(paint, std::move(colorFilter)));
+ mRecorder.drawImage(image, left, top, filterBitmap(paint, std::move(colorFilter)), bitmap.palette());
// if image->unique() is true, then mRecorder.drawImage failed for some reason. It also means
// it is not safe to store a raw SkImage pointer, because the image object will be destroyed
// when this function ends.
@@ -211,7 +209,7 @@
sk_sp<SkColorFilter> colorFilter;
sk_sp<SkImage> image = bitmap.makeImage(&colorFilter);
- mRecorder.drawImage(image, 0, 0, filterBitmap(paint, std::move(colorFilter)));
+ mRecorder.drawImage(image, 0, 0, filterBitmap(paint, std::move(colorFilter)), bitmap.palette());
if (!bitmap.isImmutable() && image.get() && !image->unique()) {
mDisplayList->mMutableImages.push_back(image.get());
}
@@ -226,7 +224,7 @@
sk_sp<SkColorFilter> colorFilter;
sk_sp<SkImage> image = bitmap.makeImage(&colorFilter);
mRecorder.drawImageRect(image, srcRect, dstRect, filterBitmap(paint, std::move(colorFilter)),
- SkCanvas::kFast_SrcRectConstraint);
+ SkCanvas::kFast_SrcRectConstraint, bitmap.palette());
if (!bitmap.isImmutable() && image.get() && !image->unique() && !srcRect.isEmpty() &&
!dstRect.isEmpty()) {
mDisplayList->mMutableImages.push_back(image.get());