Merge changes I468fe3ef,I7632c4af into main
* changes:
Fix colorspace transform with multitexture color text.
[ganesh] Add colorspace conversion for color emoji
diff --git a/src/gpu/ganesh/effects/GrAtlasedShaderHelpers.h b/src/gpu/ganesh/effects/GrAtlasedShaderHelpers.h
index 2a2fce7..1e9ae1b 100644
--- a/src/gpu/ganesh/effects/GrAtlasedShaderHelpers.h
+++ b/src/gpu/ganesh/effects/GrAtlasedShaderHelpers.h
@@ -90,11 +90,13 @@
// conditionally load from the indexed texture sampler
for (int i = 0; i < numTextureSamplers-1; ++i) {
args.fFragBuilder->codeAppendf("if (%s == %d) { %s = ", texIdx.fsIn(), i, colorName);
- args.fFragBuilder->appendTextureLookup(args.fTexSamplers[i], coordName);
+ args.fFragBuilder->appendTextureLookup(args.fTexSamplers[i],
+ coordName);
args.fFragBuilder->codeAppend("; } else ");
}
args.fFragBuilder->codeAppendf("{ %s = ", colorName);
- args.fFragBuilder->appendTextureLookup(args.fTexSamplers[numTextureSamplers - 1], coordName);
+ args.fFragBuilder->appendTextureLookup(args.fTexSamplers[numTextureSamplers - 1],
+ coordName);
args.fFragBuilder->codeAppend("; }");
}
diff --git a/src/gpu/ganesh/effects/GrBitmapTextGeoProc.cpp b/src/gpu/ganesh/effects/GrBitmapTextGeoProc.cpp
index 59e4870..4168152 100644
--- a/src/gpu/ganesh/effects/GrBitmapTextGeoProc.cpp
+++ b/src/gpu/ganesh/effects/GrBitmapTextGeoProc.cpp
@@ -12,6 +12,7 @@
#include "src/gpu/ganesh/GrShaderCaps.h"
#include "src/gpu/ganesh/GrTexture.h"
#include "src/gpu/ganesh/effects/GrAtlasedShaderHelpers.h"
+#include "src/gpu/ganesh/glsl/GrGLSLColorSpaceXformHelper.h"
#include "src/gpu/ganesh/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/ganesh/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/ganesh/glsl/GrGLSLUniformHandler.h"
@@ -42,6 +43,7 @@
}
SetTransform(pdman, shaderCaps, fLocalMatrixUniform, btgp.fLocalMatrix, &fLocalMatrix);
+ fColorSpaceXformHelper.setData(pdman, btgp.fColorSpaceXform.get());
}
private:
@@ -52,6 +54,9 @@
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
+ fColorSpaceXformHelper.emitCode(uniformHandler,
+ btgp.fColorSpaceXform.get());
+
// emit attributes
varyingHandler->emitAttributes(btgp);
@@ -91,6 +96,11 @@
fragBuilder->codeAppend("half4 texColor;");
append_multitexture_lookup(args, btgp.numTextureSamplers(),
texIdx, uv.fsIn(), "texColor");
+ if (!fColorSpaceXformHelper.isNoop()) {
+ fragBuilder->codeAppend("texColor = ");
+ fragBuilder->appendColorGamutXform("texColor", &fColorSpaceXformHelper);
+ fragBuilder->codeAppend(";");
+ }
if (btgp.fMaskFormat == MaskFormat::kARGB) {
// modulate by color
@@ -109,6 +119,8 @@
UniformHandle fColorUniform;
UniformHandle fAtlasDimensionsInvUniform;
UniformHandle fLocalMatrixUniform;
+
+ GrGLSLColorSpaceXformHelper fColorSpaceXformHelper;
};
///////////////////////////////////////////////////////////////////////////////
@@ -116,6 +128,7 @@
GrBitmapTextGeoProc::GrBitmapTextGeoProc(const GrShaderCaps& caps,
const SkPMColor4f& color,
bool wideColor,
+ sk_sp<GrColorSpaceXform> colorSpaceXform,
const GrSurfaceProxyView* views,
int numActiveViews,
GrSamplerState params,
@@ -124,6 +137,7 @@
bool usesW)
: INHERITED(kGrBitmapTextGeoProc_ClassID)
, fColor(color)
+ , fColorSpaceXform(std::move(colorSpaceXform))
, fLocalMatrix(localMatrix)
, fUsesW(usesW)
, fMaskFormat(format) {
@@ -187,6 +201,7 @@
ProgramImpl::ComputeMatrixKey(caps, fLocalMatrix),
"localMatrixType");
b->add32(this->numTextureSamplers(), "numTextures");
+ b->add32(GrColorSpaceXform::XformKey(fColorSpaceXform.get()), "colorSpaceXform");
}
std::unique_ptr<GrGeometryProcessor::ProgramImpl> GrBitmapTextGeoProc::makeProgramImpl(
@@ -229,7 +244,7 @@
bool usesW = d->fRandom->nextBool();
return GrBitmapTextGeoProc::Make(d->allocator(), *d->caps()->shaderCaps(),
SkPMColor4f::FromBytes_RGBA(color),
- wideColor,
+ wideColor, /*colorSpaceXform=*/nullptr,
&view, 1, samplerState, format,
localMatrix, usesW);
}
diff --git a/src/gpu/ganesh/effects/GrBitmapTextGeoProc.h b/src/gpu/ganesh/effects/GrBitmapTextGeoProc.h
index b406da3..a0cfcad 100644
--- a/src/gpu/ganesh/effects/GrBitmapTextGeoProc.h
+++ b/src/gpu/ganesh/effects/GrBitmapTextGeoProc.h
@@ -8,12 +8,16 @@
#ifndef GrBitmapTextGeoProc_DEFINED
#define GrBitmapTextGeoProc_DEFINED
+#include "include/core/SkRefCnt.h"
#include "src/base/SkArenaAlloc.h"
#include "src/gpu/AtlasTypes.h"
+#include "src/gpu/ganesh/GrColorSpaceXform.h"
#include "src/gpu/ganesh/GrGeometryProcessor.h"
#include "src/gpu/ganesh/GrProcessor.h"
#include "src/gpu/ganesh/GrProcessorUnitTest.h"
+#include <utility>
+
class GrGLBitmapTextGeoProc;
class GrInvariantOutput;
class GrSurfaceProxyView;
@@ -31,6 +35,7 @@
const GrShaderCaps& caps,
const SkPMColor4f& color,
bool wideColor,
+ sk_sp<GrColorSpaceXform> colorSpaceXform,
const GrSurfaceProxyView* views,
int numActiveViews,
GrSamplerState p,
@@ -38,7 +43,8 @@
const SkMatrix& localMatrix,
bool usesW) {
return arena->make([&](void* ptr) {
- return new (ptr) GrBitmapTextGeoProc(caps, color, wideColor, views, numActiveViews,
+ return new (ptr) GrBitmapTextGeoProc(caps, color, wideColor, std::move(colorSpaceXform),
+ views, numActiveViews,
p, format, localMatrix, usesW);
});
}
@@ -57,6 +63,7 @@
class Impl;
GrBitmapTextGeoProc(const GrShaderCaps&, const SkPMColor4f&, bool wideColor,
+ sk_sp<GrColorSpaceXform> colorSpaceXform,
const GrSurfaceProxyView* views, int numViews, GrSamplerState params,
skgpu::MaskFormat format, const SkMatrix& localMatrix, bool usesW);
@@ -64,15 +71,16 @@
const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; }
- SkPMColor4f fColor;
- SkMatrix fLocalMatrix;
- bool fUsesW;
- SkISize fAtlasDimensions; // dimensions for all textures used with fTextureSamplers[].
- TextureSampler fTextureSamplers[kMaxTextures];
- Attribute fInPosition;
- Attribute fInColor;
- Attribute fInTextureCoords;
- skgpu::MaskFormat fMaskFormat;
+ SkPMColor4f fColor;
+ sk_sp<GrColorSpaceXform> fColorSpaceXform;
+ SkMatrix fLocalMatrix;
+ bool fUsesW;
+ SkISize fAtlasDimensions; // dims for all textures used with fTextureSamplers
+ TextureSampler fTextureSamplers[kMaxTextures];
+ Attribute fInPosition;
+ Attribute fInColor;
+ Attribute fInTextureCoords;
+ skgpu::MaskFormat fMaskFormat;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST
diff --git a/src/gpu/ganesh/ops/AtlasTextOp.cpp b/src/gpu/ganesh/ops/AtlasTextOp.cpp
index ae222ad..3e6a7c2 100644
--- a/src/gpu/ganesh/ops/AtlasTextOp.cpp
+++ b/src/gpu/ganesh/ops/AtlasTextOp.cpp
@@ -15,6 +15,7 @@
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkStrikeCache.h"
#include "src/gpu/ganesh/GrCaps.h"
+#include "src/gpu/ganesh/GrColorSpaceXform.h"
#include "src/gpu/ganesh/GrMemoryPool.h"
#include "src/gpu/ganesh/GrOpFlushState.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
@@ -70,6 +71,7 @@
int glyphCount,
SkRect deviceRect,
Geometry* geo,
+ const GrColorInfo& dstColorInfo,
GrPaint&& paint)
: INHERITED{ClassID()}
, fProcessors(std::move(paint))
@@ -85,6 +87,10 @@
// We don't have tight bounds on the glyph paths in device space. For the purposes of bounds
// we treat this as a set of non-AA rects rendered with a texture.
this->setBounds(deviceRect, HasAABloat::kNo, IsHairline::kNo);
+ if (maskType == MaskType::kColorBitmap) {
+ // We assume that color emoji use the sRGB colorspace
+ fColorSpaceXform = dstColorInfo.refColorSpaceXformFromSRGB();
+ }
}
AtlasTextOp::AtlasTextOp(MaskType maskType,
@@ -259,7 +265,8 @@
// color, so we can use the first's without worry.
flushInfo.fGeometryProcessor = GrBitmapTextGeoProc::Make(
target->allocator(), *target->caps().shaderCaps(), fHead->fColor,
- false, views, numActiveViews, filter, maskFormat, localMatrix, fHasPerspective);
+ /*wideColor=*/false, fColorSpaceXform, views, numActiveViews, filter,
+ maskFormat, localMatrix, fHasPerspective);
}
const int vertexStride = (int)flushInfo.fGeometryProcessor->vertexStride();
diff --git a/src/gpu/ganesh/ops/AtlasTextOp.h b/src/gpu/ganesh/ops/AtlasTextOp.h
index 1f73e70..964afa5 100644
--- a/src/gpu/ganesh/ops/AtlasTextOp.h
+++ b/src/gpu/ganesh/ops/AtlasTextOp.h
@@ -9,6 +9,7 @@
#define skgpu_ganesh_AtlasTextOp_DEFINED
#include "src/gpu/AtlasTypes.h"
+#include "src/gpu/ganesh/GrColorSpaceXform.h"
#include "src/gpu/ganesh/effects/GrDistanceFieldGeoProc.h"
#include "src/gpu/ganesh/ops/GrMeshDrawOp.h"
#include "src/text/gpu/TextBlob.h"
@@ -132,6 +133,7 @@
int glyphCount,
SkRect deviceRect,
Geometry* geo,
+ const GrColorInfo& dstColorInfo,
GrPaint&& paint);
AtlasTextOp(MaskType maskType,
@@ -254,6 +256,9 @@
static_assert(kInvalid_DistanceFieldEffectFlag <= (1 << 9), "DFGP Flags do not fit in 10 bits");
#endif
+ // Only needed for color emoji
+ sk_sp<GrColorSpaceXform> fColorSpaceXform;
+
// Only used for distance fields; per-channel luminance for LCD, or gamma-corrected luminance
// for single-channel distance fields.
const SkColor fLuminanceColor{0};
diff --git a/src/gpu/ganesh/ops/SmallPathRenderer.cpp b/src/gpu/ganesh/ops/SmallPathRenderer.cpp
index 4245160..faf09b3 100644
--- a/src/gpu/ganesh/ops/SmallPathRenderer.cpp
+++ b/src/gpu/ganesh/ops/SmallPathRenderer.cpp
@@ -193,8 +193,8 @@
} else {
flushInfo.fGeometryProcessor = GrBitmapTextGeoProc::Make(
target->allocator(), *target->caps().shaderCaps(), this->color(), fWideColor,
- views, numActiveProxies, GrSamplerState::Filter::kNearest,
- MaskFormat::kA8, invert, false);
+ /*colorSpaceXform=*/nullptr, views, numActiveProxies,
+ GrSamplerState::Filter::kNearest, MaskFormat::kA8, invert, false);
}
// allocate vertices
diff --git a/src/text/gpu/SubRunContainer.cpp b/src/text/gpu/SubRunContainer.cpp
index d99bf17..981ddd8 100644
--- a/src/text/gpu/SubRunContainer.cpp
+++ b/src/text/gpu/SubRunContainer.cpp
@@ -1461,6 +1461,7 @@
this->glyphCount(),
subRunDeviceBounds,
geometry,
+ sdc->colorInfo(),
std::move(grPaint));
return {clip, std::move(op)};
}
@@ -1803,6 +1804,7 @@
this->glyphCount(),
this->deviceRect(positionMatrix),
geometry,
+ sdc->colorInfo(),
std::move(grPaint));
return {clip, std::move(op)};
}