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 bool isScaled = lowestPreScaleMipLevel != 0; |
| 374 |
| 375 SkISize scaledSize; |
| 376 if (isScaled) { |
| 377 // SkMipMap::ComputeLevelSize takes an index into an SkMipMap. SkMipMaps
don't contain the |
| 378 // base level, so to get an SkMipMap index we must subtract one from the
GL MipMap level. |
| 379 scaledSize = SkMipMap::ComputeLevelSize(this->width(), this->height(), |
| 380 lowestPreScaleMipLevel - 1); |
| 381 } else { |
| 382 scaledSize = SkISize::Make(this->width(), this->height()); |
| 383 } |
| 384 |
| 385 // We never want to scale at higher than SW medium quality, as SW medium mat
ches GPU high. |
| 386 SkFilterQuality scaleFilterQuality = highestFilterQuality; |
| 387 if (scaleFilterQuality > kMedium_SkFilterQuality) { |
| 388 scaleFilterQuality = kMedium_SkFilterQuality; |
| 389 } |
| 390 |
361 const int maxTextureSize = proxy.fCaps->maxTextureSize(); | 391 const int maxTextureSize = proxy.fCaps->maxTextureSize(); |
362 if (width() > maxTextureSize || height() > maxTextureSize) { | 392 if (scaledSize.width() > maxTextureSize || scaledSize.height() > maxTextureS
ize) { |
363 return 0; | 393 return 0; |
364 } | 394 } |
365 | 395 |
366 SkAutoPixmapStorage pixmap; | 396 SkAutoPixmapStorage pixmap; |
367 SkImageInfo info; | 397 SkImageInfo info; |
368 size_t pixelSize = 0; | 398 size_t pixelSize = 0; |
369 size_t ctSize = 0; | 399 size_t ctSize = 0; |
370 int ctCount = 0; | 400 int ctCount = 0; |
371 if (this->peekPixels(&pixmap)) { | 401 if (!isScaled && this->peekPixels(&pixmap)) { |
372 info = pixmap.info(); | 402 info = pixmap.info(); |
373 pixelSize = SkAlign8(pixmap.getSafeSize()); | 403 pixelSize = SkAlign8(pixmap.getSafeSize()); |
374 if (pixmap.ctable()) { | 404 if (pixmap.ctable()) { |
375 ctCount = pixmap.ctable()->count(); | 405 ctCount = pixmap.ctable()->count(); |
376 ctSize = SkAlign8(pixmap.ctable()->count() * 4); | 406 ctSize = SkAlign8(pixmap.ctable()->count() * 4); |
377 } | 407 } |
378 } else { | 408 } else { |
379 // Here we're just using presence of data to know whether there is a cod
ec behind the image. | 409 // 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. | 410 // In the future we will access the cacherator and get the exact data th
at we want to (e.g. |
381 // yuv planes) upload. | 411 // yuv planes) upload. |
382 SkAutoTUnref<SkData> data(this->refEncoded()); | 412 SkAutoTUnref<SkData> data(this->refEncoded()); |
383 if (!data) { | 413 if (!data && !this->peekPixels(nullptr)) { |
384 return 0; | 414 return 0; |
385 } | 415 } |
386 SkAlphaType at = this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlph
aType; | 416 SkAlphaType at = this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlph
aType; |
387 info = SkImageInfo::MakeN32(this->width(), this->height(), at); | 417 info = SkImageInfo::MakeN32(scaledSize.width(), scaledSize.height(), at)
; |
388 pixelSize = SkAlign8(SkAutoPixmapStorage::AllocSize(info, nullptr)); | 418 pixelSize = SkAlign8(SkAutoPixmapStorage::AllocSize(info, nullptr)); |
389 if (fillMode) { | 419 if (fillMode) { |
390 pixmap.alloc(info); | 420 pixmap.alloc(info); |
391 if (!this->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHint))
{ | 421 if (isScaled) { |
392 return 0; | 422 if (!this->scalePixels(pixmap, scaleFilterQuality, |
| 423 SkImage::kDisallow_CachingHint)) { |
| 424 return 0; |
| 425 } |
| 426 } else { |
| 427 if (!this->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHi
nt)) { |
| 428 return 0; |
| 429 } |
393 } | 430 } |
394 SkASSERT(!pixmap.ctable()); | 431 SkASSERT(!pixmap.ctable()); |
395 } | 432 } |
396 } | 433 } |
397 int mipMapLevelCount = 1; | 434 int mipMapLevelCount = 1; |
398 size_t size = 0; | 435 size_t size = 0; |
399 size_t dtiSize = SkAlign8(sizeof(DeferredTextureImage)); | 436 size_t dtiSize = SkAlign8(sizeof(DeferredTextureImage)); |
400 size += dtiSize; | 437 size += dtiSize; |
401 size += mipMapLevelCount * sizeof(DeferredTextureImage::MipMapLevelData); | 438 size += mipMapLevelCount * sizeof(DeferredTextureImage::MipMapLevelData); |
402 size_t pixelOffset = size; | 439 size_t pixelOffset = size; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 if (!ctx) { | 514 if (!ctx) { |
478 return nullptr; | 515 return nullptr; |
479 } | 516 } |
480 SkAutoTUnref<GrTexture> texture(GrUploadMipMapToTexture(ctx, info, texels, m
ipLevelCount)); | 517 SkAutoTUnref<GrTexture> texture(GrUploadMipMapToTexture(ctx, info, texels, m
ipLevelCount)); |
481 if (!texture) { | 518 if (!texture) { |
482 return nullptr; | 519 return nullptr; |
483 } | 520 } |
484 return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNew
ImageUniqueID, | 521 return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNew
ImageUniqueID, |
485 info.alphaType(), texture, budgeted); | 522 info.alphaType(), texture, budgeted); |
486 } | 523 } |
OLD | NEW |