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

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

Issue 2227323002: Revert of Store mipmap levels in deferred texture image (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 4 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 "GrTexturePriv.h"
14 #include "effects/GrYUVEffect.h" 13 #include "effects/GrYUVEffect.h"
15 #include "SkCanvas.h" 14 #include "SkCanvas.h"
16 #include "SkBitmapCache.h" 15 #include "SkBitmapCache.h"
17 #include "SkGrPriv.h" 16 #include "SkGrPriv.h"
18 #include "SkImage_Gpu.h" 17 #include "SkImage_Gpu.h"
19 #include "SkMipMap.h" 18 #include "SkMipMap.h"
20 #include "SkPixelRef.h" 19 #include "SkPixelRef.h"
21 20
22 SkImage_Gpu::SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType at, GrText ure* tex, 21 SkImage_Gpu::SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType at, GrText ure* tex,
23 sk_sp<SkColorSpace> colorSpace, SkBudgeted budgeted) 22 sk_sp<SkColorSpace> colorSpace, SkBudgeted budgeted)
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 357
359 //////////////////////////////////////////////////////////////////////////////// /////////////////// 358 //////////////////////////////////////////////////////////////////////////////// ///////////////////
360 359
361 namespace { 360 namespace {
362 struct MipMapLevelData { 361 struct MipMapLevelData {
363 void* fPixelData; 362 void* fPixelData;
364 size_t fRowBytes; 363 size_t fRowBytes;
365 }; 364 };
366 365
367 struct DeferredTextureImage { 366 struct DeferredTextureImage {
368 uint32_t fContextUniqueID; 367 uint32_t fContextUniqueID;
369 // Right now, the gamma treatment is only considered when generating mipmaps
370 SkSourceGammaTreatment fGammaTreatment;
371 // We don't store a SkImageInfo because it contains a ref-counted SkColorSpa ce. 368 // We don't store a SkImageInfo because it contains a ref-counted SkColorSpa ce.
372 int fWidth; 369 int fWidth;
373 int fHeight; 370 int fHeight;
374 SkColorType fColorType; 371 SkColorType fColorType;
375 SkAlphaType fAlphaType; 372 SkAlphaType fAlphaType;
376 void* fColorSpace; 373 void* fColorSpace;
377 size_t fColorSpaceSize; 374 size_t fColorSpaceSize;
378 int fColorTableCnt; 375 int fColorTableCnt;
379 uint32_t* fColorTableData; 376 uint32_t* fColorTableData;
380 int fMipMapLevelCount; 377 int fMipMapLevelCount;
381 // The fMipMapLevelData array may contain more than 1 element. 378 // The fMipMapLevelData array may contain more than 1 element.
382 // It contains fMipMapLevelCount elements. 379 // It contains fMipMapLevelCount elements.
383 // That means this struct's size is not known at compile-time. 380 // That means this struct's size is not known at compile-time.
384 MipMapLevelData fMipMapLevelData[1]; 381 MipMapLevelData fMipMapLevelData[1];
385 }; 382 };
386 } // anonymous namespace 383 } // anonymous namespace
387 384
388 static bool should_use_mip_maps(const SkImage::DeferredTextureImageUsageParams & param) {
389 bool shouldUseMipMaps = false;
390
391 // Use mipmaps if either
392 // 1.) it is a perspective matrix, or
393 // 2.) the quality is med/high and the scale is < 1
394 if (param.fMatrix.hasPerspective()) {
395 shouldUseMipMaps = true;
396 }
397 if (param.fQuality == kMedium_SkFilterQuality ||
398 param.fQuality == kHigh_SkFilterQuality) {
399 SkScalar minAxisScale = param.fMatrix.getMinScale();
400 if (minAxisScale != -1.f && minAxisScale < 1.f) {
401 shouldUseMipMaps = true;
402 }
403 }
404
405 return shouldUseMipMaps;
406 }
407
408 size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox y, 385 size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox y,
409 const DeferredTextureImageUsageParam s params[], 386 const DeferredTextureImageUsageParam s params[],
410 int paramCnt, void* buffer, 387 int paramCnt, void* buffer) const {
411 SkSourceGammaTreatment gammaTreatmen t) const {
412 // Extract relevant min/max values from the params array. 388 // Extract relevant min/max values from the params array.
413 int lowestPreScaleMipLevel = params[0].fPreScaleMipLevel; 389 int lowestPreScaleMipLevel = params[0].fPreScaleMipLevel;
414 SkFilterQuality highestFilterQuality = params[0].fQuality; 390 SkFilterQuality highestFilterQuality = params[0].fQuality;
415 bool useMipMaps = should_use_mip_maps(params[0]);
416 for (int i = 1; i < paramCnt; ++i) { 391 for (int i = 1; i < paramCnt; ++i) {
417 if (lowestPreScaleMipLevel > params[i].fPreScaleMipLevel) 392 if (lowestPreScaleMipLevel > params[i].fPreScaleMipLevel)
418 lowestPreScaleMipLevel = params[i].fPreScaleMipLevel; 393 lowestPreScaleMipLevel = params[i].fPreScaleMipLevel;
419 if (highestFilterQuality < params[i].fQuality) 394 if (highestFilterQuality < params[i].fQuality)
420 highestFilterQuality = params[i].fQuality; 395 highestFilterQuality = params[i].fQuality;
421 useMipMaps |= should_use_mip_maps(params[i]);
422 } 396 }
423 397
424 const bool fillMode = SkToBool(buffer); 398 const bool fillMode = SkToBool(buffer);
425 if (fillMode && !SkIsAlign8(reinterpret_cast<intptr_t>(buffer))) { 399 if (fillMode && !SkIsAlign8(reinterpret_cast<intptr_t>(buffer))) {
426 return 0; 400 return 0;
427 } 401 }
428 402
429 // Calculate scaling parameters. 403 // Calculate scaling parameters.
430 bool isScaled = lowestPreScaleMipLevel != 0; 404 bool isScaled = lowestPreScaleMipLevel != 0;
431 405
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 return 0; 455 return 0;
482 } 456 }
483 } else { 457 } else {
484 if (!this->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHi nt)) { 458 if (!this->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHi nt)) {
485 return 0; 459 return 0;
486 } 460 }
487 } 461 }
488 SkASSERT(!pixmap.ctable()); 462 SkASSERT(!pixmap.ctable());
489 } 463 }
490 } 464 }
491 SkAlphaType at = this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaTyp e;
492 int mipMapLevelCount = 1; 465 int mipMapLevelCount = 1;
493 if (useMipMaps) {
494 // SkMipMap only deals with the mipmap levels it generates, which does
495 // not include the base level.
496 // That means it generates and holds levels 1-x instead of 0-x.
497 // So the total mipmap level count is 1 more than what
498 // SkMipMap::ComputeLevelCount returns.
499 mipMapLevelCount = SkMipMap::ComputeLevelCount(scaledSize.width(), scale dSize.height()) + 1;
500
501 // We already initialized pixelSize to the size of the base level.
502 // SkMipMap will generate the extra mipmap levels. Their sizes need to
503 // be added to the total.
504 // Index 0 here does not refer to the base mipmap level -- it is
505 // SkMipMap's first generated mipmap level (level 1).
506 for (int currentMipMapLevelIndex = mipMapLevelCount - 1; currentMipMapLe velIndex >= 0;
507 currentMipMapLevelIndex--) {
508 SkISize mipSize = SkMipMap::ComputeLevelSize(scaledSize.width(), sca ledSize.height(),
509 currentMipMapLevelIndex );
510 SkImageInfo mipInfo = SkImageInfo::MakeN32(mipSize.fWidth, mipSize.f Height, at);
511 pixelSize += SkAlign8(SkAutoPixmapStorage::AllocSize(mipInfo, nullpt r));
512 }
513 }
514 size_t size = 0; 466 size_t size = 0;
515 size_t dtiSize = SkAlign8(sizeof(DeferredTextureImage)); 467 size_t dtiSize = SkAlign8(sizeof(DeferredTextureImage));
516 size += dtiSize; 468 size += dtiSize;
517 size += mipMapLevelCount * sizeof(MipMapLevelData); 469 size += mipMapLevelCount * sizeof(MipMapLevelData);
518 size_t pixelOffset = size; 470 size_t pixelOffset = size;
519 size += pixelSize; 471 size += pixelSize;
520 size_t ctOffset = size; 472 size_t ctOffset = size;
521 size += ctSize; 473 size += ctSize;
522 size_t colorSpaceOffset = 0; 474 size_t colorSpaceOffset = 0;
523 size_t colorSpaceSize = 0; 475 size_t colorSpaceSize = 0;
(...skipping 13 matching lines...) Expand all
537 } 489 }
538 490
539 memcpy(pixels, pixmap.addr(), pixmap.getSafeSize()); 491 memcpy(pixels, pixmap.addr(), pixmap.getSafeSize());
540 if (ctSize) { 492 if (ctSize) {
541 memcpy(ct, pixmap.ctable()->readColors(), ctSize); 493 memcpy(ct, pixmap.ctable()->readColors(), ctSize);
542 } 494 }
543 495
544 SkASSERT(info == pixmap.info()); 496 SkASSERT(info == pixmap.info());
545 size_t rowBytes = pixmap.rowBytes(); 497 size_t rowBytes = pixmap.rowBytes();
546 DeferredTextureImage* dti = new (buffer) DeferredTextureImage(); 498 DeferredTextureImage* dti = new (buffer) DeferredTextureImage();
547 dti->fGammaTreatment = gammaTreatment;
548 dti->fContextUniqueID = proxy.fContextUniqueID; 499 dti->fContextUniqueID = proxy.fContextUniqueID;
549 dti->fWidth = info.width(); 500 dti->fWidth = info.width();
550 dti->fHeight = info.height(); 501 dti->fHeight = info.height();
551 dti->fColorType = info.colorType(); 502 dti->fColorType = info.colorType();
552 dti->fAlphaType = info.alphaType(); 503 dti->fAlphaType = info.alphaType();
553 dti->fColorTableCnt = ctCount; 504 dti->fColorTableCnt = ctCount;
554 dti->fColorTableData = ct; 505 dti->fColorTableData = ct;
555 dti->fMipMapLevelCount = mipMapLevelCount; 506 dti->fMipMapLevelCount = mipMapLevelCount;
556 dti->fMipMapLevelData[0].fPixelData = pixels; 507 dti->fMipMapLevelData[0].fPixelData = pixels;
557 dti->fMipMapLevelData[0].fRowBytes = rowBytes; 508 dti->fMipMapLevelData[0].fRowBytes = rowBytes;
558 if (colorSpaceSize) { 509 if (colorSpaceSize) {
559 dti->fColorSpace = reinterpret_cast<void*>(bufferAsInt + colorSpaceOffse t); 510 dti->fColorSpace = reinterpret_cast<void*>(bufferAsInt + colorSpaceOffse t);
560 dti->fColorSpaceSize = colorSpaceSize; 511 dti->fColorSpaceSize = colorSpaceSize;
561 info.colorSpace()->writeToMemory(dti->fColorSpace); 512 info.colorSpace()->writeToMemory(dti->fColorSpace);
562 } else { 513 } else {
563 dti->fColorSpace = nullptr; 514 dti->fColorSpace = nullptr;
564 dti->fColorSpaceSize = 0; 515 dti->fColorSpaceSize = 0;
565 } 516 }
566
567 // Fill in the mipmap levels if they exist
568 intptr_t mipLevelPtr = bufferAsInt + pixelOffset + SkAlign8(SkAutoPixmapStor age::AllocSize(
569 info, nullptr));
570 if (useMipMaps) {
571 SkAutoTDelete<SkMipMap> mipmaps(SkMipMap::Build(pixmap, gammaTreatment, nullptr));
572 // SkMipMap holds only the mipmap levels it generates.
573 // A programmer can use the data they provided to SkMipMap::Build as lev el 0.
574 // So the SkMipMap provides levels 1-x but it stores them in its own
575 // range 0-(x-1).
576 for (int generatedMipLevelIndex = 0; generatedMipLevelIndex < mipMapLeve lCount - 1;
577 generatedMipLevelIndex++) {
578 SkISize mipSize = SkMipMap::ComputeLevelSize(scaledSize.width(), sca ledSize.height(),
579 generatedMipLevelIndex) ;
580 SkImageInfo mipInfo = SkImageInfo::MakeN32(mipSize.fWidth, mipSize.f Height, at);
581 SkMipMap::Level mipLevel;
582 mipmaps->getLevel(generatedMipLevelIndex, &mipLevel);
583 memcpy(reinterpret_cast<void*>(mipLevelPtr), mipLevel.fPixmap.addr() ,
584 mipLevel.fPixmap.getSafeSize());
585 dti->fMipMapLevelData[generatedMipLevelIndex + 1].fPixelData =
586 reinterpret_cast<void*>(mipLevelPtr);
587 dti->fMipMapLevelData[generatedMipLevelIndex + 1].fRowBytes =
588 mipLevel.fPixmap.rowBytes();
589 mipLevelPtr += SkAlign8(mipLevel.fPixmap.getSafeSize());
590 }
591 }
592 return size; 517 return size;
593 } 518 }
594 519
595 sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, con st void* data, 520 sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, con st void* data,
596 SkBudgeted budgeted) { 521 SkBudgeted budgeted) {
597 if (!data) { 522 if (!data) {
598 return nullptr; 523 return nullptr;
599 } 524 }
600 const DeferredTextureImage* dti = reinterpret_cast<const DeferredTextureImag e*>(data); 525 const DeferredTextureImage* dti = reinterpret_cast<const DeferredTextureImag e*>(data);
601 526
602 if (!context || context->uniqueID() != dti->fContextUniqueID) { 527 if (!context || context->uniqueID() != dti->fContextUniqueID) {
603 return nullptr; 528 return nullptr;
604 } 529 }
605 SkAutoTUnref<SkColorTable> colorTable; 530 SkAutoTUnref<SkColorTable> colorTable;
606 if (dti->fColorTableCnt) { 531 if (dti->fColorTableCnt) {
607 SkASSERT(dti->fColorTableData); 532 SkASSERT(dti->fColorTableData);
608 colorTable.reset(new SkColorTable(dti->fColorTableData, dti->fColorTable Cnt)); 533 colorTable.reset(new SkColorTable(dti->fColorTableData, dti->fColorTable Cnt));
609 } 534 }
610 int mipLevelCount = dti->fMipMapLevelCount; 535 SkASSERT(dti->fMipMapLevelCount == 1);
611 SkASSERT(mipLevelCount >= 1);
612 sk_sp<SkColorSpace> colorSpace; 536 sk_sp<SkColorSpace> colorSpace;
613 if (dti->fColorSpaceSize) { 537 if (dti->fColorSpaceSize) {
614 colorSpace = SkColorSpace::Deserialize(dti->fColorSpace, dti->fColorSpac eSize); 538 colorSpace = SkColorSpace::Deserialize(dti->fColorSpace, dti->fColorSpac eSize);
615 } 539 }
616 SkImageInfo info = SkImageInfo::Make(dti->fWidth, dti->fHeight, 540 SkImageInfo info = SkImageInfo::Make(dti->fWidth, dti->fHeight,
617 dti->fColorType, dti->fAlphaType, color Space); 541 dti->fColorType, dti->fAlphaType, color Space);
618 if (mipLevelCount == 1) { 542 SkPixmap pixmap;
619 SkPixmap pixmap; 543 pixmap.reset(info, dti->fMipMapLevelData[0].fPixelData,
620 pixmap.reset(info, dti->fMipMapLevelData[0].fPixelData, 544 dti->fMipMapLevelData[0].fRowBytes, colorTable.get());
621 dti->fMipMapLevelData[0].fRowBytes, colorTable.get()); 545 return SkImage::MakeTextureFromPixmap(context, pixmap, budgeted);
622 return SkImage::MakeTextureFromPixmap(context, pixmap, budgeted);
623 } else {
624 SkAutoTDeleteArray<GrMipLevel> texels(new GrMipLevel[mipLevelCount]);
625 for (int i = 0; i < mipLevelCount; i++) {
626 texels[i].fPixels = dti->fMipMapLevelData[i].fPixelData;
627 texels[i].fRowBytes = dti->fMipMapLevelData[i].fRowBytes;
628 }
629
630 return SkImage::MakeTextureFromMipMap(context, info, texels.get(),
631 mipLevelCount, SkBudgeted::kYes,
632 dti->fGammaTreatment);
633 }
634 } 546 }
635 547
636 //////////////////////////////////////////////////////////////////////////////// /////////////////// 548 //////////////////////////////////////////////////////////////////////////////// ///////////////////
637 549
638 GrTexture* GrDeepCopyTexture(GrTexture* src, SkBudgeted budgeted) { 550 GrTexture* GrDeepCopyTexture(GrTexture* src, SkBudgeted budgeted) {
639 GrContext* ctx = src->getContext(); 551 GrContext* ctx = src->getContext();
640 552
641 GrSurfaceDesc desc = src->desc(); 553 GrSurfaceDesc desc = src->desc();
642 GrTexture* dst = ctx->textureProvider()->createTexture(desc, budgeted, nullp tr, 0); 554 GrTexture* dst = ctx->textureProvider()->createTexture(desc, budgeted, nullp tr, 0);
643 if (!dst) { 555 if (!dst) {
644 return nullptr; 556 return nullptr;
645 } 557 }
646 558
647 const SkIRect srcR = SkIRect::MakeWH(desc.fWidth, desc.fHeight); 559 const SkIRect srcR = SkIRect::MakeWH(desc.fWidth, desc.fHeight);
648 const SkIPoint dstP = SkIPoint::Make(0, 0); 560 const SkIPoint dstP = SkIPoint::Make(0, 0);
649 ctx->copySurface(dst, src, srcR, dstP); 561 ctx->copySurface(dst, src, srcR, dstP);
650 ctx->flushSurfaceWrites(dst); 562 ctx->flushSurfaceWrites(dst);
651 return dst; 563 return dst;
652 } 564 }
653 565
654 sk_sp<SkImage> SkImage::MakeTextureFromMipMap(GrContext* ctx, const SkImageInfo& info, 566 sk_sp<SkImage> SkImage::MakeTextureFromMipMap(GrContext* ctx, const SkImageInfo& info,
655 const GrMipLevel* texels, int mipL evelCount, 567 const GrMipLevel* texels, int mipL evelCount,
656 SkBudgeted budgeted, 568 SkBudgeted budgeted) {
657 SkSourceGammaTreatment gammaTreatm ent) {
658 if (!ctx) { 569 if (!ctx) {
659 return nullptr; 570 return nullptr;
660 } 571 }
661 SkAutoTUnref<GrTexture> texture(GrUploadMipMapToTexture(ctx, info, texels, m ipLevelCount)); 572 SkAutoTUnref<GrTexture> texture(GrUploadMipMapToTexture(ctx, info, texels, m ipLevelCount));
662 if (!texture) { 573 if (!texture) {
663 return nullptr; 574 return nullptr;
664 } 575 }
665 texture->texturePriv().setGammaTreatment(gammaTreatment);
666 return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNew ImageUniqueID, 576 return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNew ImageUniqueID,
667 info.alphaType(), texture, sk_ref_sp(info.col orSpace()), 577 info.alphaType(), texture, sk_ref_sp(info.col orSpace()),
668 budgeted); 578 budgeted);
669 } 579 }
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