1 /* 2 * Copyright 2016 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 8 #include "GrBitmapTextureMaker.h" 9 10 #include "GrGpuResourcePriv.h" 11 #include "GrProxyProvider.h" 12 #include "GrRecordingContext.h" 13 #include "GrRecordingContextPriv.h" 14 #include "GrSurfaceContext.h" 15 #include "SkBitmap.h" 16 #include "SkGr.h" 17 #include "SkMipMap.h" 18 #include "SkPixelRef.h" 19 20 static bool bmp_is_alpha_only(const SkBitmap& bm) { return kAlpha_8_SkColorType == bm.colorType(); } 21 22 GrBitmapTextureMaker::GrBitmapTextureMaker(GrRecordingContext* context, const SkBitmap& bitmap, 23 bool useDecal) 24 : INHERITED(context, bitmap.width(), bitmap.height(), bmp_is_alpha_only(bitmap), useDecal) 25 , fBitmap(bitmap) { 26 if (!bitmap.isVolatile()) { 27 SkIPoint origin = bitmap.pixelRefOrigin(); 28 SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, bitmap.width(), 29 bitmap.height()); 30 GrMakeKeyFromImageID(&fOriginalKey, bitmap.pixelRef()->getGenerationID(), subset); 31 } 32 } 33 34 sk_sp<GrTextureProxy> GrBitmapTextureMaker::refOriginalTextureProxy(bool willBeMipped, 35 AllowedTexGenType onlyIfFast) { 36 if (AllowedTexGenType::kCheap == onlyIfFast) { 37 return nullptr; 38 } 39 40 GrProxyProvider* proxyProvider = this->context()->priv().proxyProvider(); 41 sk_sp<GrTextureProxy> proxy; 42 43 if (fOriginalKey.isValid()) { 44 proxy = proxyProvider->findOrCreateProxyByUniqueKey(fOriginalKey, kTopLeft_GrSurfaceOrigin); 45 if (proxy && (!willBeMipped || GrMipMapped::kYes == proxy->mipMapped())) { 46 return proxy; 47 } 48 } 49 50 if (!proxy) { 51 if (willBeMipped) { 52 proxy = proxyProvider->createMipMapProxyFromBitmap(fBitmap); 53 } 54 if (!proxy) { 55 proxy = GrUploadBitmapToTextureProxy(proxyProvider, fBitmap); 56 } 57 if (proxy) { 58 if (fOriginalKey.isValid()) { 59 proxyProvider->assignUniqueKeyToProxy(fOriginalKey, proxy.get()); 60 } 61 if (!willBeMipped || GrMipMapped::kYes == proxy->mipMapped()) { 62 SkASSERT(proxy->origin() == kTopLeft_GrSurfaceOrigin); 63 if (fOriginalKey.isValid()) { 64 GrInstallBitmapUniqueKeyInvalidator( 65 fOriginalKey, proxyProvider->contextID(), fBitmap.pixelRef()); 66 } 67 return proxy; 68 } 69 } 70 } 71 72 if (proxy) { 73 SkASSERT(willBeMipped); 74 SkASSERT(GrMipMapped::kNo == proxy->mipMapped()); 75 // We need a mipped proxy, but we either found a proxy earlier that wasn't mipped or 76 // generated a non mipped proxy. Thus we generate a new mipped surface and copy the original 77 // proxy into the base layer. We will then let the gpu generate the rest of the mips. 78 if (auto mippedProxy = GrCopyBaseMipMapToTextureProxy(this->context(), proxy.get())) { 79 SkASSERT(mippedProxy->origin() == kTopLeft_GrSurfaceOrigin); 80 if (fOriginalKey.isValid()) { 81 // In this case we are stealing the key from the original proxy which should only 82 // happen when we have just generated mipmaps for an originally unmipped 83 // proxy/texture. This means that all future uses of the key will access the 84 // mipmapped version. The texture backing the unmipped version will remain in the 85 // resource cache until the last texture proxy referencing it is deleted at which 86 // time it too will be deleted or recycled. 87 SkASSERT(proxy->getUniqueKey() == fOriginalKey); 88 proxyProvider->removeUniqueKeyFromProxy(proxy.get()); 89 proxyProvider->assignUniqueKeyToProxy(fOriginalKey, mippedProxy.get()); 90 GrInstallBitmapUniqueKeyInvalidator(fOriginalKey, proxyProvider->contextID(), 91 fBitmap.pixelRef()); 92 } 93 return mippedProxy; 94 } 95 // We failed to make a mipped proxy with the base copied into it. This could have 96 // been from failure to make the proxy or failure to do the copy. Thus we will fall 97 // back to just using the non mipped proxy; See skbug.com/7094. 98 return proxy; 99 } 100 return nullptr; 101 } 102 103 void GrBitmapTextureMaker::makeCopyKey(const CopyParams& copyParams, GrUniqueKey* copyKey) { 104 // Destination color space is irrelevant - we always upload the bitmap's contents as-is 105 if (fOriginalKey.isValid()) { 106 MakeCopyKeyFromOrigKey(fOriginalKey, copyParams, copyKey); 107 } 108 } 109 110 void GrBitmapTextureMaker::didCacheCopy(const GrUniqueKey& copyKey, uint32_t contextUniqueID) { 111 GrInstallBitmapUniqueKeyInvalidator(copyKey, contextUniqueID, fBitmap.pixelRef()); 112 } 113 114 SkAlphaType GrBitmapTextureMaker::alphaType() const { 115 return fBitmap.alphaType(); 116 } 117 118 SkColorSpace* GrBitmapTextureMaker::colorSpace() const { 119 return fBitmap.colorSpace(); 120 } 121