OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 "SkAutoPixmapStorage.h" | 8 #include "SkAutoPixmapStorage.h" |
9 #include "GrCaps.h" | 9 #include "GrCaps.h" |
10 #include "GrContext.h" | 10 #include "GrContext.h" |
11 #include "GrDrawContext.h" | 11 #include "GrDrawContext.h" |
12 #include "GrImageIDTextureAdjuster.h" | 12 #include "GrImageIDTextureAdjuster.h" |
13 #include "effects/GrYUVEffect.h" | 13 #include "effects/GrYUVEffect.h" |
14 #include "SkCanvas.h" | 14 #include "SkCanvas.h" |
15 #include "SkBitmapCache.h" | 15 #include "SkBitmapCache.h" |
16 #include "SkGrPixelRef.h" | 16 #include "SkGrPixelRef.h" |
17 #include "SkGrPriv.h" | 17 #include "SkGrPriv.h" |
18 #include "SkImage_Gpu.h" | 18 #include "SkImage_Gpu.h" |
| 19 #include "SkMipMap.h" |
19 #include "SkPixelRef.h" | 20 #include "SkPixelRef.h" |
20 | 21 |
21 SkImage_Gpu::SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType at, GrText
ure* tex, | 22 SkImage_Gpu::SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType at, GrText
ure* tex, |
22 SkBudgeted budgeted) | 23 SkBudgeted budgeted) |
23 : INHERITED(w, h, uniqueID) | 24 : INHERITED(w, h, uniqueID) |
24 , fTexture(SkRef(tex)) | 25 , fTexture(SkRef(tex)) |
25 , fAlphaType(at) | 26 , fAlphaType(at) |
26 , fBudgeted(budgeted) | 27 , fBudgeted(budgeted) |
27 , fAddedRasterVersionToCache(false) | 28 , fAddedRasterVersionToCache(false) |
28 { | 29 { |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 // It contains fMipMapLevelCount elements. | 345 // It contains fMipMapLevelCount elements. |
345 // That means this struct's size is not known at compile-time. | 346 // That means this struct's size is not known at compile-time. |
346 MipMapLevelData fMipMapLevelData[1]; | 347 MipMapLevelData fMipMapLevelData[1]; |
347 }; | 348 }; |
348 Data fData; | 349 Data fData; |
349 | 350 |
350 friend class SkImage; | 351 friend class SkImage; |
351 }; | 352 }; |
352 | 353 |
353 size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox
y, | 354 size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox
y, |
354 const DeferredTextureImageUsageParam
s[], | 355 const DeferredTextureImageUsageParam
s params[], |
355 int paramCnt, void* buffer) const { | 356 int paramCnt, void* buffer) const { |
| 357 // Extract relevant min/max values from the params array. |
| 358 int lowestPreScaleMipLevel = params[0].fPreScaleMipLevel; |
| 359 SkFilterQuality highestFilterQuality = params[0].fQuality; |
| 360 for (int i = 1; i < paramCnt; ++i) { |
| 361 if (lowestPreScaleMipLevel > params[i].fPreScaleMipLevel) |
| 362 lowestPreScaleMipLevel = params[i].fPreScaleMipLevel; |
| 363 if (highestFilterQuality < params[i].fQuality) |
| 364 highestFilterQuality = params[i].fQuality; |
| 365 } |
| 366 |
356 const bool fillMode = SkToBool(buffer); | 367 const bool fillMode = SkToBool(buffer); |
357 if (fillMode && !SkIsAlign8(reinterpret_cast<intptr_t>(buffer))) { | 368 if (fillMode && !SkIsAlign8(reinterpret_cast<intptr_t>(buffer))) { |
358 return 0; | 369 return 0; |
359 } | 370 } |
360 | 371 |
| 372 // Calculate scaling parameters. |
| 373 const SkISize scaledSize = SkMipMap::ComputeLevelSize(this->width(), this->h
eight(), |
| 374 lowestPreScaleMipLevel
); |
| 375 const bool isScaled = lowestPreScaleMipLevel != 0; |
| 376 // We never want to scale at higher than SW medium quality, as SW medium mat
ches GPU high. |
| 377 SkFilterQuality scaleFilterQuality = highestFilterQuality; |
| 378 if (scaleFilterQuality > kMedium_SkFilterQuality) { |
| 379 scaleFilterQuality = kMedium_SkFilterQuality; |
| 380 } |
| 381 |
361 const int maxTextureSize = proxy.fCaps->maxTextureSize(); | 382 const int maxTextureSize = proxy.fCaps->maxTextureSize(); |
362 if (width() > maxTextureSize || height() > maxTextureSize) { | 383 if (scaledSize.width() > maxTextureSize || scaledSize.height() > maxTextureS
ize) { |
363 return 0; | 384 return 0; |
364 } | 385 } |
365 | 386 |
366 SkAutoPixmapStorage pixmap; | 387 SkAutoPixmapStorage pixmap; |
367 SkImageInfo info; | 388 SkImageInfo info; |
368 size_t pixelSize = 0; | 389 size_t pixelSize = 0; |
369 size_t ctSize = 0; | 390 size_t ctSize = 0; |
370 int ctCount = 0; | 391 int ctCount = 0; |
371 if (this->peekPixels(&pixmap)) { | 392 if (!isScaled && this->peekPixels(&pixmap)) { |
372 info = pixmap.info(); | 393 info = pixmap.info(); |
373 pixelSize = SkAlign8(pixmap.getSafeSize()); | 394 pixelSize = SkAlign8(pixmap.getSafeSize()); |
374 if (pixmap.ctable()) { | 395 if (pixmap.ctable()) { |
375 ctCount = pixmap.ctable()->count(); | 396 ctCount = pixmap.ctable()->count(); |
376 ctSize = SkAlign8(pixmap.ctable()->count() * 4); | 397 ctSize = SkAlign8(pixmap.ctable()->count() * 4); |
377 } | 398 } |
378 } else { | 399 } else { |
379 // Here we're just using presence of data to know whether there is a cod
ec behind the image. | 400 // Here we're just using presence of data to know whether there is a cod
ec behind the image. |
380 // In the future we will access the cacherator and get the exact data th
at we want to (e.g. | 401 // In the future we will access the cacherator and get the exact data th
at we want to (e.g. |
381 // yuv planes) upload. | 402 // yuv planes) upload. |
382 SkAutoTUnref<SkData> data(this->refEncoded()); | 403 SkAutoTUnref<SkData> data(this->refEncoded()); |
383 if (!data) { | 404 if (!data && !this->peekPixels(nullptr)) { |
384 return 0; | 405 return 0; |
385 } | 406 } |
386 SkAlphaType at = this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlph
aType; | 407 SkAlphaType at = this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlph
aType; |
387 info = SkImageInfo::MakeN32(this->width(), this->height(), at); | 408 info = SkImageInfo::MakeN32(scaledSize.width(), scaledSize.height(), at)
; |
388 pixelSize = SkAlign8(SkAutoPixmapStorage::AllocSize(info, nullptr)); | 409 pixelSize = SkAlign8(SkAutoPixmapStorage::AllocSize(info, nullptr)); |
389 if (fillMode) { | 410 if (fillMode) { |
390 pixmap.alloc(info); | 411 pixmap.alloc(info); |
391 if (!this->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHint))
{ | 412 if (isScaled) { |
392 return 0; | 413 if (!this->scalePixels(pixmap, scaleFilterQuality, |
| 414 SkImage::kDisallow_CachingHint)) { |
| 415 return 0; |
| 416 } |
| 417 } else { |
| 418 if (!this->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHi
nt)) { |
| 419 return 0; |
| 420 } |
393 } | 421 } |
394 SkASSERT(!pixmap.ctable()); | 422 SkASSERT(!pixmap.ctable()); |
395 } | 423 } |
396 } | 424 } |
397 int mipMapLevelCount = 1; | 425 int mipMapLevelCount = 1; |
398 size_t size = 0; | 426 size_t size = 0; |
399 size_t dtiSize = SkAlign8(sizeof(DeferredTextureImage)); | 427 size_t dtiSize = SkAlign8(sizeof(DeferredTextureImage)); |
400 size += dtiSize; | 428 size += dtiSize; |
401 size += mipMapLevelCount * sizeof(DeferredTextureImage::MipMapLevelData); | 429 size += mipMapLevelCount * sizeof(DeferredTextureImage::MipMapLevelData); |
402 size_t pixelOffset = size; | 430 size_t pixelOffset = size; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 if (!ctx) { | 505 if (!ctx) { |
478 return nullptr; | 506 return nullptr; |
479 } | 507 } |
480 SkAutoTUnref<GrTexture> texture(GrUploadMipMapToTexture(ctx, info, texels, m
ipLevelCount)); | 508 SkAutoTUnref<GrTexture> texture(GrUploadMipMapToTexture(ctx, info, texels, m
ipLevelCount)); |
481 if (!texture) { | 509 if (!texture) { |
482 return nullptr; | 510 return nullptr; |
483 } | 511 } |
484 return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNew
ImageUniqueID, | 512 return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNew
ImageUniqueID, |
485 info.alphaType(), texture, budgeted); | 513 info.alphaType(), texture, budgeted); |
486 } | 514 } |
OLD | NEW |