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

Side by Side Diff: src/gpu/SkGr.cpp

Issue 1409163002: Rewrite GrTextureMaker to disentangle bitmap case from base class and give GPU object a say in what… (Closed) Base URL: https://skia.googlesource.com/skia.git@move
Patch Set: tidy Created 5 years, 2 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 unified diff | Download patch
« no previous file with comments | « src/gpu/GrTextureParamsAdjuster.cpp ('k') | src/gpu/SkGrPriv.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2010 Google Inc. 2 * Copyright 2010 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrTextureMaker.h"
9 8
10 #include "SkGr.h" 9 #include "SkGr.h"
11 10
12 #include "GrCaps.h" 11 #include "GrCaps.h"
13 #include "GrContext.h" 12 #include "GrContext.h"
14 #include "GrDrawContext.h" 13 #include "GrTextureParamsAdjuster.h"
14 #include "GrGpuResourcePriv.h"
15 #include "GrXferProcessor.h" 15 #include "GrXferProcessor.h"
16 #include "GrYUVProvider.h" 16 #include "GrYUVProvider.h"
17 17
18 #include "SkColorFilter.h" 18 #include "SkColorFilter.h"
19 #include "SkConfig8888.h" 19 #include "SkConfig8888.h"
20 #include "SkCanvas.h" 20 #include "SkCanvas.h"
21 #include "SkData.h" 21 #include "SkData.h"
22 #include "SkErrorInternals.h" 22 #include "SkErrorInternals.h"
23 #include "SkGrPixelRef.h" 23 #include "SkGrPixelRef.h"
24 #include "SkMessageBus.h" 24 #include "SkMessageBus.h"
(...skipping 16 matching lines...) Expand all
41 GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info) { 41 GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info) {
42 GrSurfaceDesc desc; 42 GrSurfaceDesc desc;
43 desc.fFlags = kNone_GrSurfaceFlags; 43 desc.fFlags = kNone_GrSurfaceFlags;
44 desc.fWidth = info.width(); 44 desc.fWidth = info.width();
45 desc.fHeight = info.height(); 45 desc.fHeight = info.height();
46 desc.fConfig = SkImageInfo2GrPixelConfig(info); 46 desc.fConfig = SkImageInfo2GrPixelConfig(info);
47 desc.fSampleCnt = 0; 47 desc.fSampleCnt = 0;
48 return desc; 48 return desc;
49 } 49 }
50 50
51 static void get_stretch(const GrCaps& caps, int width, int height, 51 void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& ima geBounds) {
52 const GrTextureParams& params, SkGrStretch* stretch) { 52 SkASSERT(key);
53 stretch->fType = SkGrStretch::kNone_Type; 53 SkASSERT(imageID);
54 bool doStretch = false; 54 SkASSERT(!imageBounds.isEmpty());
55 if (params.isTiled() && !caps.npotTextureTileSupport() && 55 static const GrUniqueKey::Domain kImageIDDomain = GrUniqueKey::GenerateDomai n();
56 (!SkIsPow2(width) || !SkIsPow2(height))) { 56 GrUniqueKey::Builder builder(key, kImageIDDomain, 5);
57 doStretch = true;
58 stretch->fWidth = GrNextPow2(SkTMax(width, caps.minTextureSize()));
59 stretch->fHeight = GrNextPow2(SkTMax(height, caps.minTextureSize()));
60 } else if (width < caps.minTextureSize() || height < caps.minTextureSize()) {
61 // The small texture issues appear to be with tiling. Hence it seems ok to scale them
62 // up using the GPU. If issues persist we may need to CPU-stretch.
63 doStretch = true;
64 stretch->fWidth = SkTMax(width, caps.minTextureSize());
65 stretch->fHeight = SkTMax(height, caps.minTextureSize());
66 }
67 if (doStretch) {
68 switch (params.filterMode()) {
69 case GrTextureParams::kNone_FilterMode:
70 stretch->fType = SkGrStretch::kNearest_Type;
71 break;
72 case GrTextureParams::kBilerp_FilterMode:
73 case GrTextureParams::kMipMap_FilterMode:
74 stretch->fType = SkGrStretch::kBilerp_Type;
75 break;
76 }
77 } else {
78 stretch->fWidth = -1;
79 stretch->fHeight = -1;
80 stretch->fType = SkGrStretch::kNone_Type;
81 }
82 }
83
84 static void make_unstretched_key(GrUniqueKey* key, uint32_t imageID, const SkIRe ct& subset) {
85 SkASSERT(SkIsU16(subset.width()));
86 SkASSERT(SkIsU16(subset.height()));
87
88 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
89 GrUniqueKey::Builder builder(key, kDomain, 4);
90 builder[0] = imageID; 57 builder[0] = imageID;
91 builder[1] = subset.x(); 58 builder[1] = imageBounds.fLeft;
92 builder[2] = subset.y(); 59 builder[2] = imageBounds.fTop;
93 builder[3] = subset.width() | (subset.height() << 16); 60 builder[3] = imageBounds.fRight;
94 } 61 builder[4] = imageBounds.fBottom;
95
96 void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& sub set,
97 const GrCaps& caps, const GrTextureParams& params) {
98 SkGrStretch stretch;
99 get_stretch(caps, subset.width(), subset.height(), params, &stretch);
100 if (SkGrStretch::kNone_Type != stretch.fType) {
101 GrUniqueKey tmpKey;
102 make_unstretched_key(&tmpKey, imageID, subset);
103 if (!GrMakeStretchedKey(tmpKey, stretch, key)) {
104 *key = tmpKey;
105 }
106 } else {
107 make_unstretched_key(key, imageID, subset);
108 }
109 } 62 }
110 63
111 GrPixelConfig GrIsCompressedTextureDataSupported(GrContext* ctx, SkData* data, 64 GrPixelConfig GrIsCompressedTextureDataSupported(GrContext* ctx, SkData* data,
112 int expectedW, int expectedH, 65 int expectedW, int expectedH,
113 const void** outStartOfDataToUp load) { 66 const void** outStartOfDataToUp load) {
114 *outStartOfDataToUpload = nullptr; 67 *outStartOfDataToUpload = nullptr;
115 #ifndef SK_IGNORE_ETC1_SUPPORT 68 #ifndef SK_IGNORE_ETC1_SUPPORT
116 if (!ctx->caps()->isConfigTexturable(kETC1_GrPixelConfig)) { 69 if (!ctx->caps()->isConfigTexturable(kETC1_GrPixelConfig)) {
117 return kUnknown_GrPixelConfig; 70 return kUnknown_GrPixelConfig;
118 } 71 }
(...skipping 24 matching lines...) Expand all
143 return kUnknown_GrPixelConfig; 96 return kUnknown_GrPixelConfig;
144 } 97 }
145 98
146 *outStartOfDataToUpload = ktx.pixelData(); 99 *outStartOfDataToUpload = ktx.pixelData();
147 return kETC1_GrPixelConfig; 100 return kETC1_GrPixelConfig;
148 } 101 }
149 #endif 102 #endif
150 return kUnknown_GrPixelConfig; 103 return kUnknown_GrPixelConfig;
151 } 104 }
152 105
153 /* Fill out buffer with the compressed format Ganesh expects from a colortable 106 //////////////////////////////////////////////////////////////////////////////
154 based bitmap. [palette (colortable) + indices].
155 107
156 At the moment Ganesh only supports 8bit version. If Ganesh allowed we others 108 /**
157 we could detect that the colortable.count is <= 16, and then repack the 109 * Fill out buffer with the compressed format Ganesh expects from a colortable
158 indices as nibbles to save RAM, but it would take more time (i.e. a lot 110 * based bitmap. [palette (colortable) + indices].
159 slower than memcpy), so skipping that for now. 111 *
160 112 * At the moment Ganesh only supports 8bit version. If Ganesh allowed we others
161 Ganesh wants a full 256 palette entry, even though Skia's ctable is only as big 113 * we could detect that the colortable.count is <= 16, and then repack the
162 as the colortable.count says it is. 114 * indices as nibbles to save RAM, but it would take more time (i.e. a lot
115 * slower than memcpy), so skipping that for now.
116 *
117 * Ganesh wants a full 256 palette entry, even though Skia's ctable is only as b ig
118 * as the colortable.count says it is.
163 */ 119 */
164 static void build_index8_data(void* buffer, const SkBitmap& bitmap) { 120 static void build_index8_data(void* buffer, const SkBitmap& bitmap) {
165 SkASSERT(kIndex_8_SkColorType == bitmap.colorType()); 121 SkASSERT(kIndex_8_SkColorType == bitmap.colorType());
166 122
167 SkAutoLockPixels alp(bitmap); 123 SkAutoLockPixels alp(bitmap);
168 if (!bitmap.readyToDraw()) { 124 if (!bitmap.readyToDraw()) {
169 SkDEBUGFAIL("bitmap not ready to draw!"); 125 SkDEBUGFAIL("bitmap not ready to draw!");
170 return; 126 return;
171 } 127 }
172 128
(...skipping 27 matching lines...) Expand all
200 size_t rowBytes = bitmap.rowBytes(); 156 size_t rowBytes = bitmap.rowBytes();
201 const char* src = (const char*)bitmap.getPixels(); 157 const char* src = (const char*)bitmap.getPixels();
202 for (int y = 0; y < bitmap.height(); y++) { 158 for (int y = 0; y < bitmap.height(); y++) {
203 memcpy(dst, src, width); 159 memcpy(dst, src, width);
204 src += rowBytes; 160 src += rowBytes;
205 dst += width; 161 dst += width;
206 } 162 }
207 } 163 }
208 } 164 }
209 165
210 //////////////////////////////////////////////////////////////////////////////// 166 /**
211
212
213 bool GrMakeStretchedKey(const GrUniqueKey& origKey, const SkGrStretch& stretch,
214 GrUniqueKey* stretchedKey) {
215 if (origKey.isValid() && SkGrStretch::kNone_Type != stretch.fType) {
216 uint32_t width = SkToU16(stretch.fWidth);
217 uint32_t height = SkToU16(stretch.fHeight);
218 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ;
219 GrUniqueKey::Builder builder(stretchedKey, origKey, kDomain, 2);
220 builder[0] = stretch.fType;
221 builder[1] = width | (height << 16);
222 builder.finish();
223 return true;
224 }
225 SkASSERT(!stretchedKey->isValid());
226 return false;
227 }
228
229 namespace {
230
231 // When the SkPixelRef genID changes, invalidate a corresponding GrResource desc ribed by key.
232 class BitmapInvalidator : public SkPixelRef::GenIDChangeListener {
233 public:
234 explicit BitmapInvalidator(const GrUniqueKey& key) : fMsg(key) {}
235 private:
236 GrUniqueKeyInvalidatedMessage fMsg;
237
238 void onChange() override {
239 SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg);
240 }
241 };
242
243 } // namespace
244
245
246 GrTexture* GrCreateTextureForPixels(GrContext* ctx,
247 const GrUniqueKey& optionalKey,
248 GrSurfaceDesc desc,
249 SkPixelRef* pixelRefForInvalidationNotificat ion,
250 const void* pixels,
251 size_t rowBytes) {
252 GrTexture* result = ctx->textureProvider()->createTexture(desc, true, pixels , rowBytes);
253 if (result && optionalKey.isValid()) {
254 if (pixelRefForInvalidationNotification) {
255 BitmapInvalidator* listener = new BitmapInvalidator(optionalKey);
256 pixelRefForInvalidationNotification->addGenIDChangeListener(listener );
257 }
258 ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, result);
259 }
260 return result;
261 }
262
263 // creates a new texture that is the input texture scaled up. If optionalKey is valid it will be
264 // set on the new texture. stretch controls whether the scaling is done using ne arest or bilerp
265 // filtering and the size to stretch the texture to.
266 GrTexture* stretch_texture(GrTexture* inputTexture, const SkGrStretch& stretch,
267 SkPixelRef* pixelRef,
268 const GrUniqueKey& optionalKey) {
269 SkASSERT(SkGrStretch::kNone_Type != stretch.fType);
270
271 GrContext* context = inputTexture->getContext();
272 SkASSERT(context);
273 const GrCaps* caps = context->caps();
274
275 // Either it's a cache miss or the original wasn't cached to begin with.
276 GrSurfaceDesc rtDesc = inputTexture->desc();
277 rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag;
278 rtDesc.fWidth = stretch.fWidth;
279 rtDesc.fHeight = stretch.fHeight;
280 rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig);
281
282 // If the config isn't renderable try converting to either A8 or an 32 bit c onfig. Otherwise,
283 // fail.
284 if (!caps->isConfigRenderable(rtDesc.fConfig, false)) {
285 if (GrPixelConfigIsAlphaOnly(rtDesc.fConfig)) {
286 if (caps->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
287 rtDesc.fConfig = kAlpha_8_GrPixelConfig;
288 } else if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false)) {
289 rtDesc.fConfig = kSkia8888_GrPixelConfig;
290 } else {
291 return nullptr;
292 }
293 } else if (kRGB_GrColorComponentFlags ==
294 (kRGB_GrColorComponentFlags & GrPixelConfigComponentMask(rtDe sc.fConfig))) {
295 if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false)) {
296 rtDesc.fConfig = kSkia8888_GrPixelConfig;
297 } else {
298 return nullptr;
299 }
300 } else {
301 return nullptr;
302 }
303 }
304
305 SkAutoTUnref<GrTexture> stretched(GrCreateTextureForPixels(context, optional Key, rtDesc,
306 pixelRef, nullptr ,0));
307 if (!stretched) {
308 return nullptr;
309 }
310 GrPaint paint;
311
312 // If filtering is not desired then we want to ensure all texels in the resa mpled image are
313 // copies of texels from the original.
314 GrTextureParams params(SkShader::kClamp_TileMode,
315 SkGrStretch::kBilerp_Type == stretch.fType ?
316 GrTextureParams::kBilerp_FilterMode :
317 GrTextureParams::kNone_FilterMode);
318 paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params);
319
320 SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtD esc.fHeight));
321 SkRect localRect = SkRect::MakeWH(1.f, 1.f);
322
323 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(stretched->asRe nderTarget()));
324 if (!drawContext) {
325 return nullptr;
326 }
327
328 drawContext->drawNonAARectToRect(GrClip::WideOpen(), paint, SkMatrix::I(), r ect, localRect);
329
330 return stretched.detach();
331 }
332
333 /*
334 * Once we have made SkImages handle all lazy/deferred/generated content, the Y UV apis will 167 * Once we have made SkImages handle all lazy/deferred/generated content, the Y UV apis will
335 * be gone from SkPixelRef, and we can remove this subclass entirely. 168 * be gone from SkPixelRef, and we can remove this subclass entirely.
336 */ 169 */
337 class PixelRef_GrYUVProvider : public GrYUVProvider { 170 class PixelRef_GrYUVProvider : public GrYUVProvider {
338 SkPixelRef* fPR; 171 SkPixelRef* fPR;
339 172
340 public: 173 public:
341 PixelRef_GrYUVProvider(SkPixelRef* pr) : fPR(pr) {} 174 PixelRef_GrYUVProvider(SkPixelRef* pr) : fPR(pr) {}
342 175
343 uint32_t onGetID() override { return fPR->getGenerationID(); } 176 uint32_t onGetID() override { return fPR->getGenerationID(); }
344 bool onGetYUVSizes(SkISize sizes[3]) override { 177 bool onGetYUVSizes(SkISize sizes[3]) override {
345 return fPR->getYUV8Planes(sizes, nullptr, nullptr, nullptr); 178 return fPR->getYUV8Planes(sizes, nullptr, nullptr, nullptr);
346 } 179 }
347 bool onGetYUVPlanes(SkISize sizes[3], void* planes[3], size_t rowBytes[3], 180 bool onGetYUVPlanes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
348 SkYUVColorSpace* space) override { 181 SkYUVColorSpace* space) override {
349 return fPR->getYUV8Planes(sizes, planes, rowBytes, space); 182 return fPR->getYUV8Planes(sizes, planes, rowBytes, space);
350 } 183 }
351 }; 184 };
352 185
353 static GrTexture* load_yuv_texture(GrContext* ctx, const GrUniqueKey& optionalKe y, 186 static GrTexture* create_texture_from_yuv(GrContext* ctx, const SkBitmap& bm,
354 const SkBitmap& bm, const GrSurfaceDesc& desc ) { 187 const GrSurfaceDesc& desc) {
355 // Subsets are not supported, the whole pixelRef is loaded when using YUV de coding 188 // Subsets are not supported, the whole pixelRef is loaded when using YUV de coding
356 SkPixelRef* pixelRef = bm.pixelRef(); 189 SkPixelRef* pixelRef = bm.pixelRef();
357 if ((nullptr == pixelRef) || 190 if ((nullptr == pixelRef) ||
358 (pixelRef->info().width() != bm.info().width()) || 191 (pixelRef->info().width() != bm.info().width()) ||
359 (pixelRef->info().height() != bm.info().height())) { 192 (pixelRef->info().height() != bm.info().height())) {
360 return nullptr; 193 return nullptr;
361 } 194 }
362 195
363 const bool useCache = optionalKey.isValid();
364 PixelRef_GrYUVProvider provider(pixelRef); 196 PixelRef_GrYUVProvider provider(pixelRef);
365 GrTexture* texture = provider.refAsTexture(ctx, desc, useCache);
366 if (!texture) {
367 return nullptr;
368 }
369 197
370 if (useCache) { 198 return provider.refAsTexture(ctx, desc, !bm.isVolatile());
371 BitmapInvalidator* listener = new BitmapInvalidator(optionalKey);
372 pixelRef->addGenIDChangeListener(listener);
373 ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, texture);
374 }
375 return texture;
376 } 199 }
377 200
378 static GrTexture* load_etc1_texture(GrContext* ctx, const GrUniqueKey& optionalK ey, 201 static GrTexture* load_etc1_texture(GrContext* ctx, const SkBitmap &bm, GrSurfac eDesc desc) {
379 const SkBitmap &bm, GrSurfaceDesc desc) {
380 SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData()); 202 SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData());
381 if (!data) { 203 if (!data) {
382 return nullptr; 204 return nullptr;
383 } 205 }
384 206
385 const void* startOfTexData; 207 const void* startOfTexData;
386 desc.fConfig = GrIsCompressedTextureDataSupported(ctx, data, bm.width(), bm. height(), 208 desc.fConfig = GrIsCompressedTextureDataSupported(ctx, data, bm.width(), bm. height(),
387 &startOfTexData); 209 &startOfTexData);
388 if (kUnknown_GrPixelConfig == desc.fConfig) { 210 if (kUnknown_GrPixelConfig == desc.fConfig) {
389 return nullptr; 211 return nullptr;
390 } 212 }
391 213
392 return GrCreateTextureForPixels(ctx, optionalKey, desc, bm.pixelRef(), start OfTexData, 0); 214 return ctx->textureProvider()->createTexture(desc, true, startOfTexData, 0);
393 } 215 }
394 216
395 static GrTexture* create_unstretched_bitmap_texture(GrContext* ctx, 217 GrTexture* GrUploadBitmapToTexture(GrContext* ctx, const SkBitmap& bmp) {
396 const SkBitmap& origBitmap, 218 SkASSERT(!bmp.getTexture());
397 const GrUniqueKey& optionalK ey) { 219
398 if (origBitmap.width() < ctx->caps()->minTextureSize() || 220 if (bmp.width() < ctx->caps()->minTextureSize() ||
399 origBitmap.height() < ctx->caps()->minTextureSize()) { 221 bmp.height() < ctx->caps()->minTextureSize()) {
400 return nullptr; 222 return nullptr;
401 } 223 }
224
402 SkBitmap tmpBitmap; 225 SkBitmap tmpBitmap;
403 226 const SkBitmap* bitmap = &bmp;
404 const SkBitmap* bitmap = &origBitmap;
405 227
406 GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap->info()); 228 GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap->info());
407 const GrCaps* caps = ctx->caps(); 229 const GrCaps* caps = ctx->caps();
408 230
409 if (kIndex_8_SkColorType == bitmap->colorType()) { 231 if (kIndex_8_SkColorType == bitmap->colorType()) {
410 if (caps->isConfigTexturable(kIndex_8_GrPixelConfig)) { 232 if (caps->isConfigTexturable(kIndex_8_GrPixelConfig)) {
411 size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig , 233 size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig ,
412 bitmap->width(), bitma p->height()); 234 bitmap->width(), bitma p->height());
413 SkAutoMalloc storage(imageSize); 235 SkAutoMalloc storage(imageSize);
414 build_index8_data(storage.get(), origBitmap); 236 build_index8_data(storage.get(), bmp);
415 237
416 // our compressed data will be trimmed, so pass width() for its 238 // our compressed data will be trimmed, so pass width() for its
417 // "rowBytes", since they are the same now. 239 // "rowBytes", since they are the same now.
418 return GrCreateTextureForPixels(ctx, optionalKey, desc, origBitmap.p ixelRef(), 240 return ctx->textureProvider()->createTexture(desc, true, storage.get (),
419 storage.get(), bitmap->width()); 241 bitmap->width());
420 } else { 242 } else {
421 origBitmap.copyTo(&tmpBitmap, kN32_SkColorType); 243 bmp.copyTo(&tmpBitmap, kN32_SkColorType);
422 // now bitmap points to our temp, which has been promoted to 32bits 244 // now bitmap points to our temp, which has been promoted to 32bits
423 bitmap = &tmpBitmap; 245 bitmap = &tmpBitmap;
424 desc.fConfig = SkImageInfo2GrPixelConfig(bitmap->info()); 246 desc.fConfig = SkImageInfo2GrPixelConfig(bitmap->info());
425 } 247 }
426 } else if (!bitmap->readyToDraw()) { 248 } else if (!bitmap->readyToDraw()) {
427 // If the bitmap had compressed data and was then uncompressed, it'll st ill return 249 // If the bitmap had compressed data and was then uncompressed, it'll st ill return
428 // compressed data on 'refEncodedData' and upload it. Probably not good, since if 250 // compressed data on 'refEncodedData' and upload it. Probably not good, since if
429 // the bitmap has available pixels, then they might not be what the deco mpressed 251 // the bitmap has available pixels, then they might not be what the deco mpressed
430 // data is. 252 // data is.
431 GrTexture *texture = load_etc1_texture(ctx, optionalKey, *bitmap, desc); 253
254 // Really?? We aren't doing this with YUV.
255
256 GrTexture *texture = load_etc1_texture(ctx, *bitmap, desc);
432 if (texture) { 257 if (texture) {
433 return texture; 258 return texture;
434 } 259 }
435 } 260 }
436 261
437 GrTexture *texture = load_yuv_texture(ctx, optionalKey, *bitmap, desc); 262 GrTexture *texture = create_texture_from_yuv(ctx, *bitmap, desc);
438 if (texture) { 263 if (texture) {
439 return texture; 264 return texture;
440 } 265 }
441 266
442 SkAutoLockPixels alp(*bitmap); 267 SkAutoLockPixels alp(*bitmap);
443 if (!bitmap->readyToDraw()) { 268 if (!bitmap->readyToDraw()) {
444 return nullptr; 269 return nullptr;
445 } 270 }
446 271
447 return GrCreateTextureForPixels(ctx, optionalKey, desc, origBitmap.pixelRef( ), 272 return ctx->textureProvider()->createTexture(desc, true, bitmap->getPixels() ,
448 bitmap->getPixels(), bitmap->rowBytes()); 273 bitmap->rowBytes());
449 } 274 }
450 275
451 static SkBitmap stretch_on_cpu(const SkBitmap& bmp, const SkGrStretch& stretch) {
452 SkBitmap stretched;
453 stretched.allocN32Pixels(stretch.fWidth, stretch.fHeight);
454 SkCanvas canvas(stretched);
455 SkPaint paint;
456 switch (stretch.fType) {
457 case SkGrStretch::kNearest_Type:
458 paint.setFilterQuality(kNone_SkFilterQuality);
459 break;
460 case SkGrStretch::kBilerp_Type:
461 paint.setFilterQuality(kLow_SkFilterQuality);
462 break;
463 case SkGrStretch::kNone_Type:
464 SkDEBUGFAIL("Shouldn't get here.");
465 break;
466 }
467 SkRect dstRect = SkRect::MakeWH(SkIntToScalar(stretch.fWidth), SkIntToScalar (stretch.fHeight));
468 canvas.drawBitmapRect(bmp, dstRect, &paint);
469 return stretched;
470 }
471 276
472 class Bitmap_GrTextureMaker : public GrTextureMaker { 277 ////////////////////////////////////////////////////////////////////////////////
278
279 class Bitmap_GrTextureParamsAdjuster : public GrTextureParamsAdjuster {
473 public: 280 public:
474 Bitmap_GrTextureMaker(const SkBitmap& bitmap) 281 Bitmap_GrTextureParamsAdjuster(const SkBitmap& bitmap)
475 : INHERITED(bitmap.width(), bitmap.height()) 282 : INHERITED(bitmap.width(), bitmap.height())
476 , fBitmap(bitmap) 283 , fBitmap(bitmap)
477 {} 284 {
285 if (!bitmap.isVolatile()) {
286 SkIPoint origin = bitmap.pixelRefOrigin();
287 SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, bitmap.widt h(),
288 bitmap.height());
289 GrMakeKeyFromImageID(&fOriginalKey, bitmap.pixelRef()->getGeneration ID(), subset);
290 }
291 }
478 292
479 protected: 293 protected:
480 GrTexture* onRefUnstretchedTexture(GrContext* ctx) override { 294 GrTexture* peekOriginalTexture() override { return fBitmap.getTexture(); }
295
296 GrTexture* refOriginalTexture(GrContext* ctx) override {
481 GrTexture* tex = fBitmap.getTexture(); 297 GrTexture* tex = fBitmap.getTexture();
482 if (tex) { 298 if (tex) {
483 return SkRef(tex); 299 return SkRef(tex);
484 } 300 }
485 301
486 GrUniqueKey unstretchedKey; 302 if (fOriginalKey.isValid()) {
487 make_unstretched_key(&unstretchedKey, fBitmap.getGenerationID(), fBitmap .getSubset()); 303 tex = ctx->textureProvider()->findAndRefTextureByUniqueKey(fOriginal Key);
304 if (tex) {
305 return tex;
306 }
307 }
488 308
489 GrTexture* result = ctx->textureProvider()->findAndRefTextureByUniqueKey (unstretchedKey); 309 tex = GrUploadBitmapToTexture(ctx, fBitmap);
490 if (result) { 310 if (tex && fOriginalKey.isValid()) {
491 return result; 311 tex->resourcePriv().setUniqueKey(fOriginalKey);
312 InstallInvalidator(fOriginalKey, fBitmap.pixelRef());
492 } 313 }
493 return create_unstretched_bitmap_texture(ctx, fBitmap, unstretchedKey); 314 return tex;
494 } 315 }
495 316
496 bool onMakeStretchedKey(const SkGrStretch& stretch, GrUniqueKey* stretchedKe y) override { 317 void makeCopyKey(const CopyParams& copyParams, GrUniqueKey* copyKey) overrid e {
497 if (fBitmap.isVolatile()) { 318 if (fOriginalKey.isValid()) {
498 return false; 319 MakeCopyKeyFromOrigKey(fOriginalKey, copyParams, copyKey);
499 } 320 }
500
501 GrUniqueKey unstretchedKey;
502 make_unstretched_key(&unstretchedKey, fBitmap.getGenerationID(), fBitmap .getSubset());
503 return GrMakeStretchedKey(unstretchedKey, stretch, stretchedKey);
504 } 321 }
505 322
506 void onNotifyStretchCached(const GrUniqueKey& stretchedKey) override { 323 void didCacheCopy(const GrUniqueKey& copyKey) override {
507 fBitmap.pixelRef()->addGenIDChangeListener(new BitmapInvalidator(stretch edKey)); 324 InstallInvalidator(copyKey, fBitmap.pixelRef());
508 } 325 }
509 326
510 bool onGetROBitmap(SkBitmap* bitmap) override { 327 bool getROBitmap(SkBitmap* bitmap) override {
328 SkASSERT(!fBitmap.getTexture());
511 *bitmap = fBitmap; 329 *bitmap = fBitmap;
512 return true; 330 return true;
513 } 331 }
514 332
515 private: 333 private:
516 const SkBitmap fBitmap; 334 static void InstallInvalidator(const GrUniqueKey& key, SkPixelRef* pixelRef) {
335 class Invalidator : public SkPixelRef::GenIDChangeListener {
336 public:
337 explicit Invalidator(const GrUniqueKey& key) : fMsg(key) {}
338 private:
339 GrUniqueKeyInvalidatedMessage fMsg;
517 340
518 typedef GrTextureMaker INHERITED; 341 void onChange() override {
342 SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg);
343 }
344 };
345 Invalidator* listener = new Invalidator(key);
346 pixelRef->addGenIDChangeListener(listener);
347 }
348
349 const SkBitmap fBitmap;
350 GrUniqueKey fOriginalKey;
351
352 typedef GrTextureParamsAdjuster INHERITED;
519 }; 353 };
520 354
521 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap, 355 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap,
522 const GrTextureParams& params) { 356 const GrTextureParams& params) {
523 return Bitmap_GrTextureMaker(bitmap).refCachedTexture(ctx, params); 357 return Bitmap_GrTextureParamsAdjuster(bitmap).refTextureForParams(ctx, param s);
524 } 358 }
525 359
526 /////////////////////////////////////////////////////////////////////////////// 360 ///////////////////////////////////////////////////////////////////////////////
527 361
528 // alphatype is ignore for now, but if GrPixelConfig is expanded to encompass 362 // alphatype is ignore for now, but if GrPixelConfig is expanded to encompass
529 // alpha info, that will be considered. 363 // alpha info, that will be considered.
530 GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProf ileType pt) { 364 GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProf ileType pt) {
531 switch (ct) { 365 switch (ct) {
532 case kUnknown_SkColorType: 366 case kUnknown_SkColorType:
533 return kUnknown_GrPixelConfig; 367 return kUnknown_GrPixelConfig;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 } 419 }
586 if (ctOut) { 420 if (ctOut) {
587 *ctOut = ct; 421 *ctOut = ct;
588 } 422 }
589 if (ptOut) { 423 if (ptOut) {
590 *ptOut = pt; 424 *ptOut = pt;
591 } 425 }
592 return true; 426 return true;
593 } 427 }
594 428
595
596 //////////////////////////////////////////////////////////////////////////////// //////////////// 429 //////////////////////////////////////////////////////////////////////////////// ////////////////
597 430
598 static inline bool blend_requires_shader(const SkXfermode::Mode mode, bool primi tiveIsSrc) { 431 static inline bool blend_requires_shader(const SkXfermode::Mode mode, bool primi tiveIsSrc) {
599 if (primitiveIsSrc) { 432 if (primitiveIsSrc) {
600 return SkXfermode::kSrc_Mode != mode; 433 return SkXfermode::kSrc_Mode != mode;
601 } else { 434 } else {
602 return SkXfermode::kDst_Mode != mode; 435 return SkXfermode::kDst_Mode != mode;
603 } 436 }
604 } 437 }
605 438
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 SkErrorInternals::SetError( kInvalidPaint_SkError, 668 SkErrorInternals::SetError( kInvalidPaint_SkError,
836 "Sorry, I don't understand the filtering " 669 "Sorry, I don't understand the filtering "
837 "mode you asked for. Falling back to " 670 "mode you asked for. Falling back to "
838 "MIPMaps."); 671 "MIPMaps.");
839 textureFilterMode = GrTextureParams::kMipMap_FilterMode; 672 textureFilterMode = GrTextureParams::kMipMap_FilterMode;
840 break; 673 break;
841 674
842 } 675 }
843 return textureFilterMode; 676 return textureFilterMode;
844 } 677 }
845
846 //////////////////////////////////////////////////////////////////////////////// ////////////////
847
848 GrTexture* GrTextureMaker::refCachedTexture(GrContext* ctx, const GrTextureParam s& params) {
849 SkGrStretch stretch;
850 get_stretch(*ctx->caps(), this->width(), this->height(), params, &stretch);
851
852 if (SkGrStretch::kNone_Type == stretch.fType) {
853 return this->onRefUnstretchedTexture(ctx);
854 }
855
856 GrUniqueKey stretchedKey;
857 if (this->onMakeStretchedKey(stretch, &stretchedKey)) {
858 GrTexture* result = ctx->textureProvider()->findAndRefTextureByUniqueKey (stretchedKey);
859 if (result) {
860 return result;
861 }
862 }
863
864 GrTexture* result = this->onGenerateStretchedTexture(ctx, stretch);
865 if (!result) {
866 return nullptr;
867 }
868
869 if (stretchedKey.isValid()) {
870 ctx->textureProvider()->assignUniqueKeyToTexture(stretchedKey, result);
871 this->onNotifyStretchCached(stretchedKey);
872 }
873 return result;
874 }
875
876 GrTexture* GrTextureMaker::onGenerateStretchedTexture(GrContext* ctx, const SkGr Stretch& stretch) {
877 if (this->width() < ctx->caps()->minTextureSize() ||
878 this->height() < ctx->caps()->minTextureSize())
879 {
880 // we can't trust our ability to use HW to perform the stretch, so we re quest
881 // a raster instead, and perform the stretch on the CPU.
882 SkBitmap bitmap;
883 if (!this->onGetROBitmap(&bitmap)) {
884 return nullptr;
885 }
886 SkBitmap stretchedBmp = stretch_on_cpu(bitmap, stretch);
887 return create_unstretched_bitmap_texture(ctx, stretchedBmp, GrUniqueKey( ));
888 } else {
889 SkAutoTUnref<GrTexture> unstretched(this->onRefUnstretchedTexture(ctx));
890 if (!unstretched) {
891 return nullptr;
892 }
893 return stretch_texture(unstretched, stretch, nullptr, GrUniqueKey());
894 }
895 }
OLDNEW
« no previous file with comments | « src/gpu/GrTextureParamsAdjuster.cpp ('k') | src/gpu/SkGrPriv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698