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

Side by Side Diff: src/image/SkImage_Gpu.cpp

Issue 2034933003: Store mipmap levels in deferred texture image (Closed) Base URL: https://skia.googlesource.com/skia.git@pipe-mipmap-levels-to-creation
Patch Set: Rebasing and refactoring. Created 4 years, 6 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/image/SkImage.cpp ('k') | tests/ImageTest.cpp » ('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 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 "SkMipMap.h"
20 #include "SkPixelRef.h" 20 #include "SkPixelRef.h"
21 21
22 namespace {
23 bool shouldUseMipMaps(const SkImage::DeferredTextureImageUsageParams & param) {
24 bool shouldUseMipMaps = false;
25
26 // Use mipmaps if either
27 // 1.) it is a perspective matrix, or
28 // 2.) the quality is med/high and the scale is < 1
29 if (param.fMatrix.hasPerspective()) {
30 shouldUseMipMaps = true;
31 }
32 if (param.fQuality == kMedium_SkFilterQuality ||
33 param.fQuality == kHigh_SkFilterQuality) {
34 SkScalar minAxisScale = param.fMatrix.getMinScale();
35 if (minAxisScale != -1.f && minAxisScale < 1.f) {
36 shouldUseMipMaps = true;
37 }
38 }
39
40 return shouldUseMipMaps;
41 }
42 }
43
22 SkImage_Gpu::SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType at, GrText ure* tex, 44 SkImage_Gpu::SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType at, GrText ure* tex,
23 SkBudgeted budgeted) 45 SkBudgeted budgeted)
24 : INHERITED(w, h, uniqueID) 46 : INHERITED(w, h, uniqueID)
25 , fTexture(SkRef(tex)) 47 , fTexture(SkRef(tex))
26 , fAlphaType(at) 48 , fAlphaType(at)
27 , fBudgeted(budgeted) 49 , fBudgeted(budgeted)
28 , fAddedRasterVersionToCache(false) 50 , fAddedRasterVersionToCache(false)
29 { 51 {
30 SkASSERT(tex->width() == w); 52 SkASSERT(tex->width() == w);
31 SkASSERT(tex->height() == h); 53 SkASSERT(tex->height() == h);
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 // That means this struct's size is not known at compile-time. 391 // That means this struct's size is not known at compile-time.
370 MipMapLevelData fMipMapLevelData[1]; 392 MipMapLevelData fMipMapLevelData[1];
371 }; 393 };
372 Data fData; 394 Data fData;
373 395
374 friend class SkImage; 396 friend class SkImage;
375 }; 397 };
376 398
377 size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox y, 399 size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox y,
378 const DeferredTextureImageUsageParam s params[], 400 const DeferredTextureImageUsageParam s params[],
379 int paramCnt, void* buffer) const { 401 int paramCnt, void* buffer,
402 SkSourceGammaTreatment treatment) co nst {
380 // Extract relevant min/max values from the params array. 403 // Extract relevant min/max values from the params array.
381 int lowestPreScaleMipLevel = params[0].fPreScaleMipLevel; 404 int lowestPreScaleMipLevel = params[0].fPreScaleMipLevel;
382 SkFilterQuality highestFilterQuality = params[0].fQuality; 405 SkFilterQuality highestFilterQuality = params[0].fQuality;
406 bool useMipMaps = shouldUseMipMaps(params[0]);
383 for (int i = 1; i < paramCnt; ++i) { 407 for (int i = 1; i < paramCnt; ++i) {
384 if (lowestPreScaleMipLevel > params[i].fPreScaleMipLevel) 408 if (lowestPreScaleMipLevel > params[i].fPreScaleMipLevel)
385 lowestPreScaleMipLevel = params[i].fPreScaleMipLevel; 409 lowestPreScaleMipLevel = params[i].fPreScaleMipLevel;
386 if (highestFilterQuality < params[i].fQuality) 410 if (highestFilterQuality < params[i].fQuality)
387 highestFilterQuality = params[i].fQuality; 411 highestFilterQuality = params[i].fQuality;
412 useMipMaps |= shouldUseMipMaps(params[i]);
388 } 413 }
389 414
390 const bool fillMode = SkToBool(buffer); 415 const bool fillMode = SkToBool(buffer);
391 if (fillMode && !SkIsAlign8(reinterpret_cast<intptr_t>(buffer))) { 416 if (fillMode && !SkIsAlign8(reinterpret_cast<intptr_t>(buffer))) {
392 return 0; 417 return 0;
393 } 418 }
394 419
395 // Calculate scaling parameters. 420 // Calculate scaling parameters.
396 bool isScaled = lowestPreScaleMipLevel != 0; 421 bool isScaled = lowestPreScaleMipLevel != 0;
397 422
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 return 0; 472 return 0;
448 } 473 }
449 } else { 474 } else {
450 if (!this->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHi nt)) { 475 if (!this->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHi nt)) {
451 return 0; 476 return 0;
452 } 477 }
453 } 478 }
454 SkASSERT(!pixmap.ctable()); 479 SkASSERT(!pixmap.ctable());
455 } 480 }
456 } 481 }
482 SkAlphaType at = this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaTyp e;
457 int mipMapLevelCount = 1; 483 int mipMapLevelCount = 1;
484 if (useMipMaps) {
485 // SkMipMap only deals with the mipmap levels it generates, which does
486 // not include the base level.
487 // That means it generates and holds levels 1-x instead of 0-x.
488 // So the total mipmap level count is 1 more than what
489 // SkMipMap::ComputeLevelCount returns.
490 mipMapLevelCount = SkMipMap::ComputeLevelCount(width(), height()) + 1;
491
492 // We already initialized pixelSize to the size of the base level.
493 // SkMipMap will generate the extra mipmap levels. Their sizes need to
494 // be added to the total.
495 // Index 0 here does not refer to the base mipmap level -- it is
496 // SkMipMap's first generated mipmap level (level 1).
497 for (int currentMipMapLevelIndex = mipMapLevelCount - 1; currentMipMapLe velIndex >= 0;
498 currentMipMapLevelIndex--) {
499 SkISize mipSize = SkMipMap::ComputeLevelSize(this->width(), this->he ight(),
500 currentMipMapLevelIndex );
501 SkImageInfo mipInfo = SkImageInfo::MakeN32(mipSize.fWidth, mipSize.f Height, at);
502 pixelSize += SkAlign8(SkAutoPixmapStorage::AllocSize(mipInfo, nullpt r));
503 }
504 }
458 size_t size = 0; 505 size_t size = 0;
459 size_t dtiSize = SkAlign8(sizeof(DeferredTextureImage)); 506 size_t dtiSize = SkAlign8(sizeof(DeferredTextureImage));
460 size += dtiSize; 507 size += dtiSize;
461 size += mipMapLevelCount * sizeof(DeferredTextureImage::MipMapLevelData); 508 size += mipMapLevelCount * sizeof(DeferredTextureImage::MipMapLevelData);
462 size_t pixelOffset = size; 509 size_t pixelOffset = size;
463 size += pixelSize; 510 size += pixelSize;
464 size_t ctOffset = size; 511 size_t ctOffset = size;
465 size += ctSize; 512 size += ctSize;
466 if (!fillMode) { 513 if (!fillMode) {
467 return size; 514 return size;
(...skipping 13 matching lines...) Expand all
481 SkASSERT(info == pixmap.info()); 528 SkASSERT(info == pixmap.info());
482 size_t rowBytes = pixmap.rowBytes(); 529 size_t rowBytes = pixmap.rowBytes();
483 DeferredTextureImage* dti = new (buffer) DeferredTextureImage(); 530 DeferredTextureImage* dti = new (buffer) DeferredTextureImage();
484 dti->fContextUniqueID = proxy.fContextUniqueID; 531 dti->fContextUniqueID = proxy.fContextUniqueID;
485 dti->fData.fInfo = info; 532 dti->fData.fInfo = info;
486 dti->fData.fColorTableCnt = ctCount; 533 dti->fData.fColorTableCnt = ctCount;
487 dti->fData.fColorTableData = ct; 534 dti->fData.fColorTableData = ct;
488 dti->fData.fMipMapLevelCount = mipMapLevelCount; 535 dti->fData.fMipMapLevelCount = mipMapLevelCount;
489 dti->fData.fMipMapLevelData[0].fPixelData = pixels; 536 dti->fData.fMipMapLevelData[0].fPixelData = pixels;
490 dti->fData.fMipMapLevelData[0].fRowBytes = rowBytes; 537 dti->fData.fMipMapLevelData[0].fRowBytes = rowBytes;
538
539 // Fill in the mipmap levels if they exist
540 intptr_t mipLevelPtr = bufferAsInt + pixelOffset + SkAlign8(SkAutoPixmapStor age::AllocSize(
541 info, nullptr));
542 if (useMipMaps) {
543 SkAutoTDelete<SkMipMap> mipmaps(SkMipMap::Build(pixmap, treatment, nullp tr));
544 // SkMipMap holds only the mipmap levels it generates.
545 // A programmer can use the data they provided to SkMipMap::Build as lev el 0.
546 // So the SkMipMap provides levels 1-x but it stores them in its own
547 // range 0-(x-1).
548 for (int generatedMipLevelIndex = 0; generatedMipLevelIndex < mipMapLeve lCount - 1;
549 generatedMipLevelIndex++) {
550 SkISize mipSize = SkMipMap::ComputeLevelSize(width(), height(),
551 generatedMipLevelIndex) ;
552 SkImageInfo mipInfo = SkImageInfo::MakeN32(mipSize.fWidth, mipSize.f Height, at);
553 SkMipMap::Level mipLevel;
554 mipmaps->getLevel(generatedMipLevelIndex, &mipLevel);
555 memcpy(reinterpret_cast<void*>(mipLevelPtr), mipLevel.fPixmap.addr() ,
556 mipLevel.fPixmap.getSafeSize());
557 dti->fData.fMipMapLevelData[generatedMipLevelIndex + 1].fPixelData =
558 reinterpret_cast<void*>(mipLevelPtr);
559 dti->fData.fMipMapLevelData[generatedMipLevelIndex + 1].fRowBytes =
560 mipLevel.fPixmap.rowBytes();
561 mipLevelPtr += SkAlign8(mipLevel.fPixmap.getSafeSize());
562 }
563 }
491 return size; 564 return size;
492 } 565 }
493 566
494 sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, con st void* data, 567 sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, con st void* data,
495 SkBudgeted budgeted) { 568 SkBudgeted budgeted) {
496 if (!data) { 569 if (!data) {
497 return nullptr; 570 return nullptr;
498 } 571 }
499 const DeferredTextureImage* dti = reinterpret_cast<const DeferredTextureImag e*>(data); 572 const DeferredTextureImage* dti = reinterpret_cast<const DeferredTextureImag e*>(data);
500 573
501 if (!context || context->uniqueID() != dti->fContextUniqueID) { 574 if (!context || context->uniqueID() != dti->fContextUniqueID) {
502 return nullptr; 575 return nullptr;
503 } 576 }
504 SkAutoTUnref<SkColorTable> colorTable; 577 SkAutoTUnref<SkColorTable> colorTable;
505 if (dti->fData.fColorTableCnt) { 578 if (dti->fData.fColorTableCnt) {
506 SkASSERT(dti->fData.fColorTableData); 579 SkASSERT(dti->fData.fColorTableData);
507 colorTable.reset(new SkColorTable(dti->fData.fColorTableData, dti->fData .fColorTableCnt)); 580 colorTable.reset(new SkColorTable(dti->fData.fColorTableData, dti->fData .fColorTableCnt));
508 } 581 }
509 SkASSERT(dti->fData.fMipMapLevelCount == 1); 582 int mipLevelCount = dti->fData.fMipMapLevelCount;
510 SkPixmap pixmap; 583 SkASSERT(mipLevelCount >= 1);
511 pixmap.reset(dti->fData.fInfo, dti->fData.fMipMapLevelData[0].fPixelData, 584 if (mipLevelCount == 1) {
512 dti->fData.fMipMapLevelData[0].fRowBytes, colorTable.get()); 585 SkPixmap pixmap;
513 return SkImage::MakeTextureFromPixmap(context, pixmap, budgeted); 586 pixmap.reset(dti->fData.fInfo, dti->fData.fMipMapLevelData[0].fPixelData ,
587 dti->fData.fMipMapLevelData[0].fRowBytes, colorTable.get()) ;
588 return SkImage::MakeTextureFromPixmap(context, pixmap, budgeted);
589 } else {
590 SkAutoTDeleteArray<GrMipLevel> texels(new GrMipLevel[mipLevelCount]);
591 for (int i = 0; i < mipLevelCount; i++) {
592 texels[i].fPixels = dti->fData.fMipMapLevelData[i].fPixelData;
593 texels[i].fRowBytes = dti->fData.fMipMapLevelData[i].fRowBytes;
594 }
595
596 return SkImage::MakeTextureFromMipMap(context, dti->fData.fInfo, texels. get(),
597 mipLevelCount, SkBudgeted::kYes);
598 }
514 } 599 }
515 600
516 //////////////////////////////////////////////////////////////////////////////// /////////////////// 601 //////////////////////////////////////////////////////////////////////////////// ///////////////////
517 602
518 GrTexture* GrDeepCopyTexture(GrTexture* src, SkBudgeted budgeted) { 603 GrTexture* GrDeepCopyTexture(GrTexture* src, SkBudgeted budgeted) {
519 GrContext* ctx = src->getContext(); 604 GrContext* ctx = src->getContext();
520 605
521 GrSurfaceDesc desc = src->desc(); 606 GrSurfaceDesc desc = src->desc();
522 GrTexture* dst = ctx->textureProvider()->createTexture(desc, budgeted, nullp tr, 0); 607 GrTexture* dst = ctx->textureProvider()->createTexture(desc, budgeted, nullp tr, 0);
523 if (!dst) { 608 if (!dst) {
(...skipping 10 matching lines...) Expand all
534 sk_sp<SkImage> SkImage::MakeTextureFromMipMap(GrContext* ctx, const SkImageInfo& info, 619 sk_sp<SkImage> SkImage::MakeTextureFromMipMap(GrContext* ctx, const SkImageInfo& info,
535 const GrMipLevel* texels, int mipL evelCount, 620 const GrMipLevel* texels, int mipL evelCount,
536 SkBudgeted budgeted) { 621 SkBudgeted budgeted) {
537 if (!ctx) { 622 if (!ctx) {
538 return nullptr; 623 return nullptr;
539 } 624 }
540 SkAutoTUnref<GrTexture> texture(GrUploadMipMapToTexture(ctx, info, texels, m ipLevelCount)); 625 SkAutoTUnref<GrTexture> texture(GrUploadMipMapToTexture(ctx, info, texels, m ipLevelCount));
541 if (!texture) { 626 if (!texture) {
542 return nullptr; 627 return nullptr;
543 } 628 }
544 return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNew ImageUniqueID, 629 return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNew ImageUniqueID,
Brian Osman 2016/06/14 12:10:51 FYI: Ganesh needs to know the gamma treatment valu
cblume 2016/06/14 20:44:29 Done. Should we also be thinking about gamma trea
545 info.alphaType(), texture, budgeted); 630 info.alphaType(), texture, budgeted);
546 } 631 }
OLDNEW
« no previous file with comments | « src/image/SkImage.cpp ('k') | tests/ImageTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698