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

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: Fixing Windows build. 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
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 "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 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 // It contains fMipMapLevelCount elements. 368 // It contains fMipMapLevelCount elements.
368 // That means this struct's size is not known at compile-time. 369 // That means this struct's size is not known at compile-time.
369 MipMapLevelData fMipMapLevelData[1]; 370 MipMapLevelData fMipMapLevelData[1];
370 }; 371 };
371 Data fData; 372 Data fData;
372 373
373 friend class SkImage; 374 friend class SkImage;
374 }; 375 };
375 376
376 size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox y, 377 size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox y,
377 const DeferredTextureImageUsageParam s[], 378 const DeferredTextureImageUsageParam s params[],
378 int paramCnt, void* buffer) const { 379 int paramCnt, void* buffer,
380 SkSourceGammaTreatment treatment) co nst {
381 bool shouldUseMipMaps = false;
382 for (int currentParamIndex = paramCnt - 1; currentParamIndex >= 0; currentPa ramIndex--) {
383 const SkMatrix& currentMatrix = params[currentParamIndex].fMatrix;
384 SkFilterQuality currentFilterQuality = params[currentParamIndex].fQualit y;
385
386 // Use mipmaps if either
387 // 1.) it is a perspective matrix, or
388 // 2.) the quality is med/high and the scale is < 1
389 if (currentMatrix.hasPerspective()) {
390 shouldUseMipMaps = true;
391 }
392 if (currentFilterQuality == kMedium_SkFilterQuality ||
393 currentFilterQuality == kHigh_SkFilterQuality) {
394 SkScalar minAxisScale = currentMatrix.getMinScale();
395 if (minAxisScale != -1.f && minAxisScale < 1.f) {
396 shouldUseMipMaps = true;
397 }
398 }
399 }
400
379 const bool fillMode = SkToBool(buffer); 401 const bool fillMode = SkToBool(buffer);
380 if (fillMode && !SkIsAlign8(reinterpret_cast<intptr_t>(buffer))) { 402 if (fillMode && !SkIsAlign8(reinterpret_cast<intptr_t>(buffer))) {
381 return 0; 403 return 0;
382 } 404 }
383 405
384 const int maxTextureSize = proxy.fCaps->maxTextureSize(); 406 const int maxTextureSize = proxy.fCaps->maxTextureSize();
385 if (width() > maxTextureSize || height() > maxTextureSize) { 407 if (width() > maxTextureSize || height() > maxTextureSize) {
386 return 0; 408 return 0;
387 } 409 }
388 410
(...skipping 21 matching lines...) Expand all
410 info = SkImageInfo::MakeN32(this->width(), this->height(), at); 432 info = SkImageInfo::MakeN32(this->width(), this->height(), at);
411 pixelSize = SkAlign8(SkAutoPixmapStorage::AllocSize(info, nullptr)); 433 pixelSize = SkAlign8(SkAutoPixmapStorage::AllocSize(info, nullptr));
412 if (fillMode) { 434 if (fillMode) {
413 pixmap.alloc(info); 435 pixmap.alloc(info);
414 if (!this->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHint)) { 436 if (!this->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHint)) {
415 return 0; 437 return 0;
416 } 438 }
417 SkASSERT(!pixmap.ctable()); 439 SkASSERT(!pixmap.ctable());
418 } 440 }
419 } 441 }
442 SkAlphaType at = this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaTyp e;
420 int mipMapLevelCount = 1; 443 int mipMapLevelCount = 1;
444 if (shouldUseMipMaps) {
445 // SkMipMap only deals with the mipmap levels it generates, which does
446 // not include the base level.
447 // That means it generates and holds levels 1-x instead of 0-x.
448 // So the total mipmap level count is 1 more than what
449 // SkMipMap::ComputeLevelCount returns.
450 mipMapLevelCount = SkMipMap::ComputeLevelCount(width(), height()) + 1;
451
452 // We already initialized pixelSize to the size of the base level.
453 // SkMipMap will generate the extra mipmap levels. Their sizes need to
454 // be added to the total.
455 // Index 0 here does not refer to the base mipmap level -- it is
456 // SkMipMap's first generated mipmap level (level 1).
457 for (int currentMipMapLevelIndex = mipMapLevelCount - 1; currentMipMapLe velIndex >= 0;
458 currentMipMapLevelIndex--) {
459 SkISize mipSize = SkMipMap::ComputeLevelSize(width(), height(), curr entMipMapLevelIndex);
bsalomon 2016/06/13 14:11:39 nit: wrap at 100col and this->width()/this->height
cblume 2016/06/13 18:17:16 Done.
460 SkImageInfo mipInfo = SkImageInfo::MakeN32(mipSize.fWidth, mipSize.f Height, at);
461 pixelSize += SkAlign8(SkAutoPixmapStorage::AllocSize(mipInfo, nullpt r));
462 }
463 }
421 size_t size = 0; 464 size_t size = 0;
422 size_t dtiSize = SkAlign8(sizeof(DeferredTextureImage)); 465 size_t dtiSize = SkAlign8(sizeof(DeferredTextureImage));
423 size += dtiSize; 466 size += dtiSize;
424 size += mipMapLevelCount * sizeof(DeferredTextureImage::MipMapLevelData); 467 size += mipMapLevelCount * sizeof(DeferredTextureImage::MipMapLevelData);
425 size_t pixelOffset = size; 468 size_t pixelOffset = size;
426 size += pixelSize; 469 size += pixelSize;
427 size_t ctOffset = size; 470 size_t ctOffset = size;
428 size += ctSize; 471 size += ctSize;
429 if (!fillMode) { 472 if (!fillMode) {
430 return size; 473 return size;
(...skipping 13 matching lines...) Expand all
444 SkASSERT(info == pixmap.info()); 487 SkASSERT(info == pixmap.info());
445 size_t rowBytes = pixmap.rowBytes(); 488 size_t rowBytes = pixmap.rowBytes();
446 DeferredTextureImage* dti = new (buffer) DeferredTextureImage(); 489 DeferredTextureImage* dti = new (buffer) DeferredTextureImage();
447 dti->fContextUniqueID = proxy.fContextUniqueID; 490 dti->fContextUniqueID = proxy.fContextUniqueID;
448 dti->fData.fInfo = info; 491 dti->fData.fInfo = info;
449 dti->fData.fColorTableCnt = ctCount; 492 dti->fData.fColorTableCnt = ctCount;
450 dti->fData.fColorTableData = ct; 493 dti->fData.fColorTableData = ct;
451 dti->fData.fMipMapLevelCount = mipMapLevelCount; 494 dti->fData.fMipMapLevelCount = mipMapLevelCount;
452 dti->fData.fMipMapLevelData[0].fPixelData = pixels; 495 dti->fData.fMipMapLevelData[0].fPixelData = pixels;
453 dti->fData.fMipMapLevelData[0].fRowBytes = rowBytes; 496 dti->fData.fMipMapLevelData[0].fRowBytes = rowBytes;
497
498 // Fill in the mipmap levels if they exist
499 intptr_t mipLevelPtr = bufferAsInt + pixelOffset + SkAlign8(SkAutoPixmapStor age::AllocSize(
500 info, nullptr));
501 if (shouldUseMipMaps) {
502 SkAutoTDelete<SkMipMap> mipmaps(SkMipMap::Build(pixmap, treatment, nullp tr));
503 // SkMipMap holds only the mipmap levels it generates.
504 // A programmer can use the data they provided to SkMipMap::Build as lev el 0.
505 // So the SkMipMap provides levels 1-x but it stores them in its own
506 // range 0-(x-1).
507 for (int generatedMipLevelIndex = 0; generatedMipLevelIndex < mipMapLeve lCount - 1;
508 generatedMipLevelIndex++) {
509 SkISize mipSize = SkMipMap::ComputeLevelSize(width(), height(),
510 generatedMipLevelIndex) ;
511 SkImageInfo mipInfo = SkImageInfo::MakeN32(mipSize.fWidth, mipSize.f Height, at);
512 SkMipMap::Level mipLevel;
513 mipmaps->getLevel(generatedMipLevelIndex, &mipLevel);
514 memcpy(reinterpret_cast<void*>(mipLevelPtr), mipLevel.fPixmap.addr() ,
515 mipLevel.fPixmap.getSafeSize());
516 dti->fData.fMipMapLevelData[generatedMipLevelIndex + 1].fPixelData =
517 reinterpret_cast<void*>(mipLevelPtr);
518 dti->fData.fMipMapLevelData[generatedMipLevelIndex + 1].fRowBytes =
519 mipLevel.fPixmap.rowBytes();
520 mipLevelPtr += SkAlign8(mipLevel.fPixmap.getSafeSize());
521 }
522 }
454 return size; 523 return size;
455 } 524 }
456 525
457 sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, con st void* data, 526 sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, con st void* data,
458 SkBudgeted budgeted) { 527 SkBudgeted budgeted) {
459 if (!data) { 528 if (!data) {
460 return nullptr; 529 return nullptr;
461 } 530 }
462 const DeferredTextureImage* dti = reinterpret_cast<const DeferredTextureImag e*>(data); 531 const DeferredTextureImage* dti = reinterpret_cast<const DeferredTextureImag e*>(data);
463 532
464 if (!context || context->uniqueID() != dti->fContextUniqueID) { 533 if (!context || context->uniqueID() != dti->fContextUniqueID) {
465 return nullptr; 534 return nullptr;
466 } 535 }
467 SkAutoTUnref<SkColorTable> colorTable; 536 SkAutoTUnref<SkColorTable> colorTable;
468 if (dti->fData.fColorTableCnt) { 537 if (dti->fData.fColorTableCnt) {
469 SkASSERT(dti->fData.fColorTableData); 538 SkASSERT(dti->fData.fColorTableData);
470 colorTable.reset(new SkColorTable(dti->fData.fColorTableData, dti->fData .fColorTableCnt)); 539 colorTable.reset(new SkColorTable(dti->fData.fColorTableData, dti->fData .fColorTableCnt));
471 } 540 }
472 SkASSERT(dti->fData.fMipMapLevelCount == 1); 541 int mipLevelCount = dti->fData.fMipMapLevelCount;
473 SkPixmap pixmap; 542 SkASSERT(mipLevelCount >= 1);
474 pixmap.reset(dti->fData.fInfo, dti->fData.fMipMapLevelData[0].fPixelData, 543 if (mipLevelCount == 1) {
475 dti->fData.fMipMapLevelData[0].fRowBytes, colorTable.get()); 544 SkPixmap pixmap;
476 return SkImage::MakeTextureFromPixmap(context, pixmap, budgeted); 545 pixmap.reset(dti->fData.fInfo, dti->fData.fMipMapLevelData[0].fPixelData ,
546 dti->fData.fMipMapLevelData[0].fRowBytes, colorTable.get()) ;
547 return SkImage::MakeTextureFromPixmap(context, pixmap, budgeted);
548 } else {
549 SkAutoTDeleteArray<GrMipLevel> texels(new GrMipLevel[mipLevelCount]);
550 for (int i = 0; i < mipLevelCount; i++) {
551 texels[i].fPixels = dti->fData.fMipMapLevelData[i].fPixelData;
552 texels[i].fRowBytes = dti->fData.fMipMapLevelData[i].fRowBytes;
553 }
554
555 return SkImage::MakeTextureFromMipMap(context, dti->fData.fInfo, texels. get(),
556 mipLevelCount, SkBudgeted::kYes);
557 }
477 } 558 }
478 559
479 //////////////////////////////////////////////////////////////////////////////// /////////////////// 560 //////////////////////////////////////////////////////////////////////////////// ///////////////////
480 561
481 GrTexture* GrDeepCopyTexture(GrTexture* src, SkBudgeted budgeted) { 562 GrTexture* GrDeepCopyTexture(GrTexture* src, SkBudgeted budgeted) {
482 GrContext* ctx = src->getContext(); 563 GrContext* ctx = src->getContext();
483 564
484 GrSurfaceDesc desc = src->desc(); 565 GrSurfaceDesc desc = src->desc();
485 GrTexture* dst = ctx->textureProvider()->createTexture(desc, budgeted, nullp tr, 0); 566 GrTexture* dst = ctx->textureProvider()->createTexture(desc, budgeted, nullp tr, 0);
486 if (!dst) { 567 if (!dst) {
(...skipping 13 matching lines...) Expand all
500 if (!ctx) { 581 if (!ctx) {
501 return nullptr; 582 return nullptr;
502 } 583 }
503 SkAutoTUnref<GrTexture> texture(GrUploadMipMapToTexture(ctx, info, texels, m ipLevelCount)); 584 SkAutoTUnref<GrTexture> texture(GrUploadMipMapToTexture(ctx, info, texels, m ipLevelCount));
504 if (!texture) { 585 if (!texture) {
505 return nullptr; 586 return nullptr;
506 } 587 }
507 return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNew ImageUniqueID, 588 return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNew ImageUniqueID,
508 info.alphaType(), texture, budgeted); 589 info.alphaType(), texture, budgeted);
509 } 590 }
OLDNEW
« include/core/SkImage.h ('K') | « src/image/SkImage.cpp ('k') | tests/ImageTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698