Merge "Make auto-dark a bit better"
This commit is contained in:
committed by
Android (Google) Code Review
commit
ae8cef615b
@@ -28,6 +28,7 @@
|
||||
#include <cmath>
|
||||
|
||||
#include <log/log.h>
|
||||
#include <SkHighContrastFilter.h>
|
||||
|
||||
namespace android::uirenderer {
|
||||
|
||||
@@ -113,4 +114,20 @@ bool transformPaint(ColorTransform transform, SkPaint* paint) {
|
||||
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
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hwui/Bitmap.h"
|
||||
|
||||
#include <SkCanvas.h>
|
||||
#include <SkPaintFilterCanvas.h>
|
||||
|
||||
@@ -26,6 +28,7 @@ namespace android::uirenderer {
|
||||
enum class UsageHint {
|
||||
Unknown = 0,
|
||||
Background = 1,
|
||||
Foreground = 2,
|
||||
};
|
||||
|
||||
enum class ColorTransform {
|
||||
@@ -37,4 +40,6 @@ enum class ColorTransform {
|
||||
// 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;
|
||||
@@ -278,8 +278,8 @@ struct DrawPicture final : Op {
|
||||
|
||||
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 @@ struct DrawImage final : Op {
|
||||
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 DrawImageNine final : Op {
|
||||
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 @@ struct DrawImageRect final : Op {
|
||||
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 @@ void DisplayListData::drawPicture(const SkPicture* picture, const SkMatrix* matr
|
||||
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::drawImageNine(sk_sp<const SkImage> image, const SkIRect& c
|
||||
}
|
||||
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 @@ void DisplayListData::drawText(const void* text, size_t bytes, SkScalar x, SkSca
|
||||
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 @@ void DisplayListData::reset() {
|
||||
}
|
||||
|
||||
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::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScala
|
||||
|
||||
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::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);
|
||||
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::onDrawImageNine(const SkImage* img, const SkIRect& center,
|
||||
}
|
||||
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) {
|
||||
|
||||
@@ -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 RecordingCanvas;
|
||||
|
||||
class DisplayListData final {
|
||||
public:
|
||||
DisplayListData() : mHasText(false) {}
|
||||
~DisplayListData();
|
||||
|
||||
void draw(SkCanvas* canvas) const;
|
||||
@@ -62,6 +64,8 @@ public:
|
||||
|
||||
void applyColorTransform(ColorTransform transform);
|
||||
|
||||
bool hasText() const { return mHasText; }
|
||||
|
||||
private:
|
||||
friend class RecordingCanvas;
|
||||
|
||||
@@ -101,10 +105,10 @@ private:
|
||||
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 @@ private:
|
||||
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 @@ public:
|
||||
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;
|
||||
|
||||
@@ -272,8 +272,12 @@ void RenderNode::syncDisplayList(TreeObserver& observer, TreeInfo* info) {
|
||||
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;
|
||||
|
||||
@@ -107,7 +107,7 @@ public:
|
||||
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(); }
|
||||
|
||||
@@ -330,15 +330,6 @@ sk_sp<SkImage> Bitmap::makeImage(sk_sp<SkColorFilter>* outputColorFilter) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -132,7 +132,6 @@ void SkiaDisplayList::reset() {
|
||||
mChildFunctors.clear();
|
||||
mChildNodes.clear();
|
||||
|
||||
projectionReceiveIndex = -1;
|
||||
allocator.~LinearAllocator();
|
||||
new (&allocator) LinearAllocator();
|
||||
}
|
||||
|
||||
@@ -49,9 +49,6 @@ namespace skiapipeline {
|
||||
*/
|
||||
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 @@ public:
|
||||
*/
|
||||
bool hasVectorDrawables() const { return !mVectorDrawables.empty(); }
|
||||
|
||||
bool hasText() const { return mDisplayList.hasText(); }
|
||||
|
||||
/**
|
||||
* Attempts to reset and reuse this DisplayList.
|
||||
*
|
||||
|
||||
@@ -113,8 +113,6 @@ void SkiaRecordingCanvas::drawRenderNode(uirenderer::RenderNode* renderNode) {
|
||||
// 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 @@ SkiaCanvas::PaintCoW&& SkiaRecordingCanvas::filterBitmap(PaintCoW&& paint,
|
||||
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 @@ void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, con
|
||||
|
||||
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 @@ void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop
|
||||
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());
|
||||
|
||||
Reference in New Issue
Block a user