Use raster mipmap levels when drawing to GPU.
Previously just the base level was uploaded and the level contents were generated on the GPU. showmiplevels_explicit now works on GPU. Bug: skia:11983 Change-Id: I96ed8a7ad90a8252f55a736cb6146eec9b2a3ad1 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/521356 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
fcbf28849b
commit
84e2586f15
@ -48,11 +48,6 @@ class ShowMipLevels3 : public skiagm::GM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DrawResult onDraw(SkCanvas* canvas, SkString*) override {
|
DrawResult onDraw(SkCanvas* canvas, SkString*) override {
|
||||||
if (canvas->recordingContext()) {
|
|
||||||
// mips not supported yet
|
|
||||||
return DrawResult::kSkip;
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas->drawColor(0xFFDDDDDD);
|
canvas->drawColor(0xFFDDDDDD);
|
||||||
|
|
||||||
canvas->translate(10, 10);
|
canvas->translate(10, 10);
|
||||||
|
@ -1191,6 +1191,7 @@ private:
|
|||||||
|
|
||||||
friend class SkImage_Raster;
|
friend class SkImage_Raster;
|
||||||
friend class SkReadBuffer; // unflatten
|
friend class SkReadBuffer; // unflatten
|
||||||
|
friend class GrProxyProvider; // fMips
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -269,11 +269,11 @@ GrSurfaceProxyView GrProxyProvider::findCachedProxyWithColorTypeFallback(
|
|||||||
}
|
}
|
||||||
|
|
||||||
sk_sp<GrTextureProxy> GrProxyProvider::createProxyFromBitmap(const SkBitmap& bitmap,
|
sk_sp<GrTextureProxy> GrProxyProvider::createProxyFromBitmap(const SkBitmap& bitmap,
|
||||||
GrMipmapped mipMapped,
|
GrMipmapped mipmapped,
|
||||||
SkBackingFit fit,
|
SkBackingFit fit,
|
||||||
SkBudgeted budgeted) {
|
SkBudgeted budgeted) {
|
||||||
ASSERT_SINGLE_OWNER
|
ASSERT_SINGLE_OWNER
|
||||||
SkASSERT(fit == SkBackingFit::kExact || mipMapped == GrMipmapped::kNo);
|
SkASSERT(fit == SkBackingFit::kExact || mipmapped == GrMipmapped::kNo);
|
||||||
|
|
||||||
if (this->isAbandoned()) {
|
if (this->isAbandoned()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -296,12 +296,22 @@ sk_sp<GrTextureProxy> GrProxyProvider::createProxyFromBitmap(const SkBitmap& bit
|
|||||||
if (!bitmap.readPixels(copyBitmap.pixmap())) {
|
if (!bitmap.readPixels(copyBitmap.pixmap())) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
if (mipmapped == GrMipmapped::kYes && bitmap.fMips) {
|
||||||
|
copyBitmap.fMips = sk_sp<SkMipmap>(SkMipmap::Build(copyBitmap.pixmap(),
|
||||||
|
nullptr,
|
||||||
|
false));
|
||||||
|
for (int i = 0; i < copyBitmap.fMips->countLevels(); ++i) {
|
||||||
|
SkMipmap::Level src, dst;
|
||||||
|
bitmap.fMips->getLevel(i, &src);
|
||||||
|
copyBitmap.fMips->getLevel(i, &dst);
|
||||||
|
src.fPixmap.readPixels(dst.fPixmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
copyBitmap.setImmutable();
|
copyBitmap.setImmutable();
|
||||||
}
|
}
|
||||||
|
|
||||||
sk_sp<GrTextureProxy> proxy;
|
sk_sp<GrTextureProxy> proxy;
|
||||||
if (mipMapped == GrMipmapped::kNo ||
|
if (mipmapped == GrMipmapped::kNo || !SkMipmap::ComputeLevelCount(copyBitmap.dimensions())) {
|
||||||
0 == SkMipmap::ComputeLevelCount(copyBitmap.width(), copyBitmap.height())) {
|
|
||||||
proxy = this->createNonMippedProxyFromBitmap(copyBitmap, fit, budgeted);
|
proxy = this->createNonMippedProxyFromBitmap(copyBitmap, fit, budgeted);
|
||||||
} else {
|
} else {
|
||||||
proxy = this->createMippedProxyFromBitmap(copyBitmap, budgeted);
|
proxy = this->createMippedProxyFromBitmap(copyBitmap, budgeted);
|
||||||
@ -372,9 +382,12 @@ sk_sp<GrTextureProxy> GrProxyProvider::createMippedProxyFromBitmap(const SkBitma
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
sk_sp<SkMipmap> mipmaps(SkMipmap::Build(bitmap.pixmap(), nullptr));
|
sk_sp<SkMipmap> mipmaps = bitmap.fMips;
|
||||||
if (!mipmaps) {
|
if (!mipmaps) {
|
||||||
return nullptr;
|
mipmaps.reset(SkMipmap::Build(bitmap.pixmap(), nullptr));
|
||||||
|
if (!mipmaps) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto dims = bitmap.dimensions();
|
auto dims = bitmap.dimensions();
|
||||||
@ -404,7 +417,7 @@ sk_sp<GrTextureProxy> GrProxyProvider::createMippedProxyFromBitmap(const SkBitma
|
|||||||
GrRenderable::kNo,
|
GrRenderable::kNo,
|
||||||
1,
|
1,
|
||||||
desc.fBudgeted,
|
desc.fBudgeted,
|
||||||
GrMipMapped::kYes,
|
GrMipmapped::kYes,
|
||||||
GrProtected::kNo,
|
GrProtected::kNo,
|
||||||
texels.get()));
|
texels.get()));
|
||||||
},
|
},
|
||||||
|
@ -444,7 +444,7 @@ std::tuple<GrSurfaceProxyView, GrColorType> SkImage_Raster::onAsView(
|
|||||||
if (fPinnedView) {
|
if (fPinnedView) {
|
||||||
// We ignore the mipmap request here. If the pinned view isn't mipmapped then we will
|
// We ignore the mipmap request here. If the pinned view isn't mipmapped then we will
|
||||||
// fallback to bilinear. The pin API is used by Android Framework which does not expose
|
// fallback to bilinear. The pin API is used by Android Framework which does not expose
|
||||||
// mipmapping.Moreover, we're moving towards requiring that images be made with mip levels
|
// mipmapping .Moreover, we're moving towards requiring that images be made with mip levels
|
||||||
// if mipmapping is desired (skbug.com/10411)
|
// if mipmapping is desired (skbug.com/10411)
|
||||||
mipmapped = GrMipmapped::kNo;
|
mipmapped = GrMipmapped::kNo;
|
||||||
if (policy != GrImageTexGenPolicy::kDraw) {
|
if (policy != GrImageTexGenPolicy::kDraw) {
|
||||||
@ -453,6 +453,13 @@ std::tuple<GrSurfaceProxyView, GrColorType> SkImage_Raster::onAsView(
|
|||||||
return {fPinnedView, fPinnedColorType};
|
return {fPinnedView, fPinnedColorType};
|
||||||
}
|
}
|
||||||
if (policy == GrImageTexGenPolicy::kDraw) {
|
if (policy == GrImageTexGenPolicy::kDraw) {
|
||||||
|
// If the draw doesn't require mipmaps but this SkImage has them go ahead and make a
|
||||||
|
// mipmapped texture. There are three reasons for this:
|
||||||
|
// 1) Avoiding another texture creation if a later draw requires mipmaps.
|
||||||
|
// 2) Ensuring we upload the bitmap's levels instead of generating on the GPU from the base.
|
||||||
|
if (this->hasMipmaps()) {
|
||||||
|
mipmapped = GrMipmapped::kYes;
|
||||||
|
}
|
||||||
return GrMakeCachedBitmapProxyView(rContext, fBitmap, mipmapped);
|
return GrMakeCachedBitmapProxyView(rContext, fBitmap, mipmapped);
|
||||||
}
|
}
|
||||||
auto budgeted = (policy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted)
|
auto budgeted = (policy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted)
|
||||||
|
Loading…
Reference in New Issue
Block a user