Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1956)

Unified Diff: src/core/SkMipMap.cpp

Issue 2029373004: respect srgb gamma when building mips (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix warning Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkMipMap.h ('k') | src/core/SkPM4fPriv.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkMipMap.cpp
diff --git a/src/core/SkMipMap.cpp b/src/core/SkMipMap.cpp
index 355c1edebbd755c55305e5f15b53ce510328f9ab..69c8466f69c30073fe0ace194254ef2215575959 100644
--- a/src/core/SkMipMap.cpp
+++ b/src/core/SkMipMap.cpp
@@ -11,6 +11,7 @@
#include "SkHalf.h"
#include "SkMathPriv.h"
#include "SkNx.h"
+#include "SkPM4fPriv.h"
#include "SkTypes.h"
//
@@ -41,6 +42,16 @@ struct ColorTypeFilter_8888 {
#endif
};
+struct ColorTypeFilter_S32 {
+ typedef uint32_t Type;
+ static Sk4f Expand(uint32_t x) {
+ return Sk4f_fromS32(x);
+ }
+ static uint32_t Compact(const Sk4f& x) {
+ return Sk4f_toS32(x);
+ }
+};
+
struct ColorTypeFilter_565 {
typedef uint16_t Type;
static uint32_t Expand(uint16_t x) {
@@ -293,7 +304,16 @@ size_t SkMipMap::AllocLevelsSize(int levelCount, size_t pixelSize) {
return sk_64_asS32(size);
}
-SkMipMap* SkMipMap::Build(const SkPixmap& src, SkDiscardableFactoryProc fact) {
+static bool treat_like_srgb(const SkImageInfo& info) {
+ if (info.colorSpace()) {
+ return SkColorSpace::k2Dot2Curve_GammaNamed == info.colorSpace()->gammaNamed();
+ } else {
+ return kSRGB_SkColorProfileType == info.profileType();
+ }
+}
+
+SkMipMap* SkMipMap::Build(const SkPixmap& src, SkSourceGammaTreatment treatment,
+ SkDiscardableFactoryProc fact) {
typedef void FilterProc(void*, const void* srcPtr, size_t srcRB, int count);
FilterProc* proc_1_2 = nullptr;
@@ -307,17 +327,31 @@ SkMipMap* SkMipMap::Build(const SkPixmap& src, SkDiscardableFactoryProc fact) {
const SkColorType ct = src.colorType();
const SkAlphaType at = src.alphaType();
+ const bool srgbGamma = (SkSourceGammaTreatment::kRespect == treatment)
+ && treat_like_srgb(src.info());
+
switch (ct) {
case kRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType:
- proc_1_2 = downsample_1_2<ColorTypeFilter_8888>;
- proc_1_3 = downsample_1_3<ColorTypeFilter_8888>;
- proc_2_1 = downsample_2_1<ColorTypeFilter_8888>;
- proc_2_2 = downsample_2_2<ColorTypeFilter_8888>;
- proc_2_3 = downsample_2_3<ColorTypeFilter_8888>;
- proc_3_1 = downsample_3_1<ColorTypeFilter_8888>;
- proc_3_2 = downsample_3_2<ColorTypeFilter_8888>;
- proc_3_3 = downsample_3_3<ColorTypeFilter_8888>;
+ if (srgbGamma) {
+ proc_1_2 = downsample_1_2<ColorTypeFilter_S32>;
+ proc_1_3 = downsample_1_3<ColorTypeFilter_S32>;
+ proc_2_1 = downsample_2_1<ColorTypeFilter_S32>;
+ proc_2_2 = downsample_2_2<ColorTypeFilter_S32>;
+ proc_2_3 = downsample_2_3<ColorTypeFilter_S32>;
+ proc_3_1 = downsample_3_1<ColorTypeFilter_S32>;
+ proc_3_2 = downsample_3_2<ColorTypeFilter_S32>;
+ proc_3_3 = downsample_3_3<ColorTypeFilter_S32>;
+ } else {
+ proc_1_2 = downsample_1_2<ColorTypeFilter_8888>;
+ proc_1_3 = downsample_1_3<ColorTypeFilter_8888>;
+ proc_2_1 = downsample_2_1<ColorTypeFilter_8888>;
+ proc_2_2 = downsample_2_2<ColorTypeFilter_8888>;
+ proc_2_3 = downsample_2_3<ColorTypeFilter_8888>;
+ proc_3_1 = downsample_3_1<ColorTypeFilter_8888>;
+ proc_3_2 = downsample_3_2<ColorTypeFilter_8888>;
+ proc_3_3 = downsample_3_3<ColorTypeFilter_8888>;
+ }
break;
case kRGB_565_SkColorType:
proc_1_2 = downsample_1_2<ColorTypeFilter_565>;
@@ -394,8 +428,10 @@ SkMipMap* SkMipMap::Build(const SkPixmap& src, SkDiscardableFactoryProc fact) {
}
// init
+ mipmap->fCS = sk_ref_sp(src.info().colorSpace());
mipmap->fCount = countLevels;
mipmap->fLevels = (Level*)mipmap->writable_data();
+ SkASSERT(mipmap->fLevels);
Level* levels = mipmap->fLevels;
uint8_t* baseAddr = (uint8_t*)&levels[countLevels];
@@ -440,6 +476,9 @@ SkMipMap* SkMipMap::Build(const SkPixmap& src, SkDiscardableFactoryProc fact) {
height = SkTMax(1, height >> 1);
rowBytes = SkToU32(SkColorTypeMinRowBytes(ct, width));
+ // We make the Info w/o any colorspace, since that storage is not under our control, and
+ // will not be deleted in a controlled fashion. When the caller is given the pixmap for
+ // a given level, we augment this pixmap with fCS (which we do manage).
new (&levels[i].fPixmap) SkPixmap(SkImageInfo::Make(width, height, ct, at), addr, rowBytes);
levels[i].fScale = SkSize::Make(SkIntToScalar(width) / src.width(),
SkIntToScalar(height) / src.height());
@@ -459,6 +498,7 @@ SkMipMap* SkMipMap::Build(const SkPixmap& src, SkDiscardableFactoryProc fact) {
}
SkASSERT(addr == baseAddr + size);
+ SkASSERT(mipmap->fLevels);
return mipmap;
}
@@ -547,9 +587,7 @@ bool SkMipMap::extractLevel(const SkSize& scaleSize, Level* levelPtr) const {
return false;
}
SkASSERT(L >= 0);
-// int rndLevel = SkScalarRoundToInt(L);
int level = SkScalarFloorToInt(L);
-// SkDebugf("mipmap scale=%g L=%g level=%d rndLevel=%d\n", scale, L, level, rndLevel);
SkASSERT(level >= 0);
if (level <= 0) {
@@ -561,13 +599,16 @@ bool SkMipMap::extractLevel(const SkSize& scaleSize, Level* levelPtr) const {
}
if (levelPtr) {
*levelPtr = fLevels[level - 1];
+ // need to augment with our colorspace
+ levelPtr->fPixmap.setColorSpace(fCS);
}
return true;
}
// Helper which extracts a pixmap from the src bitmap
//
-SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) {
+SkMipMap* SkMipMap::Build(const SkBitmap& src, SkSourceGammaTreatment treatment,
+ SkDiscardableFactoryProc fact) {
SkAutoPixmapUnlock srcUnlocker;
if (!src.requestLock(&srcUnlocker)) {
return nullptr;
@@ -577,7 +618,7 @@ SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) {
if (nullptr == srcPixmap.addr()) {
sk_throw();
}
- return Build(srcPixmap, fact);
+ return Build(srcPixmap, treatment, fact);
}
int SkMipMap::countLevels() const {
« no previous file with comments | « src/core/SkMipMap.h ('k') | src/core/SkPM4fPriv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698