Flutter Engine
The Flutter Engine
SkMipmapAccessor.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
14#include "include/core/SkSize.h"
18#include "src/core/SkMipmap.h"
20
21class SkImage;
22
23// Try to load from the base image, or from the cache
25 sk_sp<const SkMipmap> mips = image->refMips();
26 if (!mips) {
28 }
29 if (!mips) {
31 }
32 return mips;
33}
34
36 SkMipmapMode requestedMode) {
37 SkMipmapMode resolvedMode = requestedMode;
38 fLowerWeight = 0;
39
40 auto load_upper_from_base = [&]() {
41 // only do this once
42 if (fBaseStorage.getPixels() == nullptr) {
43 auto dContext = as_IB(image)->directContext();
44 (void)image->getROPixels(dContext, &fBaseStorage);
45 fUpper.reset(fBaseStorage.info(), fBaseStorage.getPixels(), fBaseStorage.rowBytes());
46 }
47 };
48
49 float level = 0;
50 if (requestedMode != SkMipmapMode::kNone) {
52 if (!inv.decomposeScale(&scale, nullptr)) {
53 resolvedMode = SkMipmapMode::kNone;
54 } else {
55 level = SkMipmap::ComputeLevel({1/scale.width(), 1/scale.height()});
56 if (level <= 0) {
57 resolvedMode = SkMipmapMode::kNone;
58 level = 0;
59 }
60 }
61 }
62
63 auto scale = [image](const SkPixmap& pm) {
64 return SkMatrix::Scale(SkIntToScalar(pm.width()) / image->width(),
65 SkIntToScalar(pm.height()) / image->height());
66 };
67
68 // Nearest mode uses this level, so we round to pick the nearest. In linear mode we use this
69 // level as the lower of the two to interpolate between, so we take the floor.
70 int levelNum = resolvedMode == SkMipmapMode::kNearest ? sk_float_round2int(level)
72 float lowerWeight = level - levelNum; // fract(level)
73 SkASSERT(levelNum >= 0);
74
75 if (levelNum == 0) {
76 load_upper_from_base();
77 }
78 // load fCurrMip if needed
79 if (levelNum > 0 || (resolvedMode == SkMipmapMode::kLinear && lowerWeight > 0)) {
80 fCurrMip = try_load_mips(image);
81 if (!fCurrMip) {
82 load_upper_from_base();
83 resolvedMode = SkMipmapMode::kNone;
84 } else {
85 SkMipmap::Level levelRec;
86
87 SkASSERT(resolvedMode != SkMipmapMode::kNone);
88 if (levelNum > 0) {
89 if (fCurrMip->getLevel(levelNum - 1, &levelRec)) {
90 fUpper = levelRec.fPixmap;
91 } else {
92 load_upper_from_base();
93 resolvedMode = SkMipmapMode::kNone;
94 }
95 }
96
97 if (resolvedMode == SkMipmapMode::kLinear) {
98 if (fCurrMip->getLevel(levelNum, &levelRec)) {
99 fLower = levelRec.fPixmap;
100 fLowerWeight = lowerWeight;
101 fLowerInv = scale(fLower);
102 } else {
103 resolvedMode = SkMipmapMode::kNearest;
104 }
105 }
106 }
107 }
108 fUpperInv = scale(fUpper);
109}
110
112 const SkMatrix& inv, SkMipmapMode mipmap) {
113 auto* access = alloc->make<SkMipmapAccessor>(as_IB(image), inv, mipmap);
114 // return null if we failed to get the level (so the caller won't try to use it)
115 return access->fUpper.addr() ? access : nullptr;
116}
static SkM44 inv(const SkM44 &m)
Definition: 3d.cpp:26
#define SkASSERT(cond)
Definition: SkAssert.h:116
#define sk_float_round2int(x)
#define sk_float_floor2int(x)
static SkImage_Base * as_IB(SkImage *image)
Definition: SkImage_Base.h:201
static sk_sp< const SkMipmap > try_load_mips(const SkImage_Base *image)
SkMipmapMode
#define SkIntToScalar(x)
Definition: SkScalar.h:57
const SkScalar fLower
Definition: TextWrapper.cpp:45
const SkScalar fUpper
Definition: TextWrapper.cpp:45
auto make(Ctor &&ctor) -> decltype(ctor(nullptr))
Definition: SkArenaAlloc.h:120
size_t rowBytes() const
Definition: SkBitmap.h:238
void * getPixels() const
Definition: SkBitmap.h:283
const SkImageInfo & info() const
Definition: SkBitmap.h:139
virtual GrDirectContext * directContext() const
Definition: SkImage_Base.h:115
int width() const
Definition: SkImage.h:285
int height() const
Definition: SkImage.h:291
static SkMatrix Scale(SkScalar sx, SkScalar sy)
Definition: SkMatrix.h:75
float lowerWeight() const
static SkMipmapAccessor * Make(SkArenaAlloc *, const SkImage *, const SkMatrix &inv, SkMipmapMode)
std::pair< SkPixmap, SkMatrix > level() const
SkMipmapAccessor(const SkImage_Base *, const SkMatrix &inv, SkMipmapMode requestedMode)
static const SkMipmap * AddAndRef(const SkImage_Base *, SkResourceCache *localCache=nullptr)
static const SkMipmap * FindAndRef(const SkBitmapCacheDesc &, SkResourceCache *localCache=nullptr)
static float ComputeLevel(SkSize scaleSize)
Definition: SkMipmap.cpp:195
bool getLevel(int index, Level *) const
Definition: SkMipmap.cpp:280
const void * addr() const
Definition: SkPixmap.h:153
void reset(T *ptr=nullptr)
Definition: SkRefCnt.h:310
sk_sp< const SkImage > image
Definition: SkRecords.h:269
const Scalar scale
static SkBitmapCacheDesc Make(const SkImage *)
SkPixmap fPixmap
Definition: SkMipmap.h:71
Definition: SkSize.h:52