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

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: Keeping support for non-mipmapped images the same. 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
« src/image/SkImage.cpp ('K') | « src/image/SkImage.cpp ('k') | no next file » | 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 "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 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 // It contains fMipMapLevelCount elements. 356 // It contains fMipMapLevelCount elements.
356 // That means this struct's size is not known at compile-time. 357 // That means this struct's size is not known at compile-time.
357 MipMapLevelData fMipMapLevelData[1]; 358 MipMapLevelData fMipMapLevelData[1];
358 }; 359 };
359 Data fData; 360 Data fData;
360 361
361 friend class SkImage; 362 friend class SkImage;
362 }; 363 };
363 364
364 size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox y, 365 size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox y,
365 const DeferredTextureImageUsageParam s[], 366 const DeferredTextureImageUsageParam s params[],
366 int paramCnt, void* buffer) const { 367 int paramCnt, void* buffer) const {
367 const bool fillMode = SkToBool(buffer); 368 const bool fillMode = SkToBool(buffer);
368 if (fillMode && !SkIsAlign8(reinterpret_cast<intptr_t>(buffer))) { 369 if (fillMode && !SkIsAlign8(reinterpret_cast<intptr_t>(buffer))) {
369 return 0; 370 return 0;
370 } 371 }
371 372
372 const int maxTextureSize = proxy.fCaps->maxTextureSize(); 373 const int maxTextureSize = proxy.fCaps->maxTextureSize();
373 if (width() > maxTextureSize || height() > maxTextureSize) { 374 if (width() > maxTextureSize || height() > maxTextureSize) {
374 return 0; 375 return 0;
375 } 376 }
(...skipping 22 matching lines...) Expand all
398 info = SkImageInfo::MakeN32(this->width(), this->height(), at); 399 info = SkImageInfo::MakeN32(this->width(), this->height(), at);
399 pixelSize = SkAlign8(SkAutoPixmapStorage::AllocSize(info, nullptr)); 400 pixelSize = SkAlign8(SkAutoPixmapStorage::AllocSize(info, nullptr));
400 if (fillMode) { 401 if (fillMode) {
401 pixmap.alloc(info); 402 pixmap.alloc(info);
402 if (!this->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHint)) { 403 if (!this->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHint)) {
403 return 0; 404 return 0;
404 } 405 }
405 SkASSERT(!pixmap.ctable()); 406 SkASSERT(!pixmap.ctable());
406 } 407 }
407 } 408 }
409 bool shouldUseMipMaps = false;
408 int mipMapLevelCount = 1; 410 int mipMapLevelCount = 1;
411 for (int currentParamIndex = paramCnt; currentParamIndex > 0; currentParamIn dex--) {
412 SkScalar minScaleFactor = params[currentParamIndex].fMatrix.getMinScale( );
413 if ((params[currentParamIndex].fQuality == kMedium_SkFilterQuality ||
414 params[currentParamIndex].fQuality == kHigh_SkFilterQuality) &&
415 minScaleFactor != -1.f && minScaleFactor < 1.f) {
bsalomon 2016/06/03 14:43:33 Do we not use mip maps when the matrix has perspec
cblume 2016/06/03 17:03:40 Hrmmm I think any time perspective is involved it
416 shouldUseMipMaps = true;
417 mipMapLevelCount = SkMipMap::ComputeLevelCount(width(), height());
418 break;
419 }
420 }
421 SkAlphaType at = this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaTyp e;
422 if (shouldUseMipMaps) {
423 for (int currentMipMapLevelIndex = mipMapLevelCount; currentMipMapLevelI ndex > 0;
424 currentMipMapLevelIndex--) {
425 SkSize mipSize = SkMipMap::ComputeLevelSize(width(), height(), curre ntMipMapLevelIndex);
426 SkImageInfo mipInfo = SkImageInfo::MakeN32(mipSize.fWidth, mipSize.f Height, at);
427 pixelSize += SkAlign8(SkAutoPixmapStorage::AllocSize(mipInfo, nullpt r));
428 }
429 }
409 size_t size = 0; 430 size_t size = 0;
410 size_t dtiSize = SkAlign8(sizeof(DeferredTextureImage)); 431 size_t dtiSize = SkAlign8(sizeof(DeferredTextureImage));
411 size += dtiSize; 432 size += dtiSize;
412 size += mipMapLevelCount * sizeof(DeferredTextureImage::MipMapLevelData); 433 size += mipMapLevelCount * sizeof(DeferredTextureImage::MipMapLevelData);
413 size_t pixelOffset = size; 434 size_t pixelOffset = size;
414 size += pixelSize; 435 size += pixelSize;
415 size_t ctOffset = size; 436 size_t ctOffset = size;
416 size += ctSize; 437 size += ctSize;
417 if (!fillMode) { 438 if (!fillMode) {
418 return size; 439 return size;
(...skipping 13 matching lines...) Expand all
432 SkASSERT(info == pixmap.info()); 453 SkASSERT(info == pixmap.info());
433 size_t rowBytes = pixmap.rowBytes(); 454 size_t rowBytes = pixmap.rowBytes();
434 DeferredTextureImage* dti = new (buffer) DeferredTextureImage(); 455 DeferredTextureImage* dti = new (buffer) DeferredTextureImage();
435 dti->fContextUniqueID = proxy.fContextUniqueID; 456 dti->fContextUniqueID = proxy.fContextUniqueID;
436 dti->fData.fInfo = info; 457 dti->fData.fInfo = info;
437 dti->fData.fColorTableCnt = ctCount; 458 dti->fData.fColorTableCnt = ctCount;
438 dti->fData.fColorTableData = ct; 459 dti->fData.fColorTableData = ct;
439 dti->fData.fMipMapLevelCount = mipMapLevelCount; 460 dti->fData.fMipMapLevelCount = mipMapLevelCount;
440 dti->fData.fMipMapLevelData[0].fPixelData = pixels; 461 dti->fData.fMipMapLevelData[0].fPixelData = pixels;
441 dti->fData.fMipMapLevelData[0].fRowBytes = rowBytes; 462 dti->fData.fMipMapLevelData[0].fRowBytes = rowBytes;
463
464 // Fill in the mipmap levels if they exist
465 intptr_t mipLevelPtr = bufferAsInt + pixelOffset;
466 if (shouldUseMipMaps) {
467 SkAutoTDelete<SkMipMap> mipmaps(SkMipMap::Build(pixmap, nullptr));
468 for (int currentMipMapLevelIndex = 1; currentMipMapLevelIndex < mipMapLe velCount;
469 currentMipMapLevelIndex++) {
470 SkSize prevMipSize = SkMipMap::ComputeLevelSize(width(), height(), c urrentMipMapLevelIndex);
471 SkImageInfo prevMipInfo = SkImageInfo::MakeN32(prevMipSize.fWidth, p revMipSize.fHeight, at);
472 mipLevelPtr += SkAlign8(SkAutoPixmapStorage::AllocSize(prevMipInfo, nullptr));
473
474 SkMipMap::Level currentMipMapLevel;
475 mipmaps->getLevel(currentMipMapLevelIndex, &currentMipMapLevel);
476 memcpy(reinterpret_cast<void*>(mipLevelPtr), currentMipMapLevel.fPix map.addr(),
bsalomon 2016/06/03 14:43:33 It's too bad we have to memcpy here. Should we ext
cblume 2016/06/03 17:03:40 I agree @ memcpy. I would love to add a CL that mo
477 currentMipMapLevel.fPixmap.getSafeSize());
478 dti->fData.fMipMapLevelData[currentMipMapLevelIndex].fPixelData =
479 reinterpret_cast<void*>(mipLevelPtr);
480 dti->fData.fMipMapLevelData[currentMipMapLevelIndex].fRowBytes =
481 currentMipMapLevel.fPixmap.rowBytes();
482 }
483 }
442 return size; 484 return size;
443 } 485 }
444 486
445 sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, con st void* data, 487 sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, con st void* data,
446 SkBudgeted budgeted) { 488 SkBudgeted budgeted) {
447 if (!data) { 489 if (!data) {
448 return nullptr; 490 return nullptr;
449 } 491 }
450 const DeferredTextureImage* dti = reinterpret_cast<const DeferredTextureImag e*>(data); 492 const DeferredTextureImage* dti = reinterpret_cast<const DeferredTextureImag e*>(data);
451 493
452 if (!context || context->uniqueID() != dti->fContextUniqueID) { 494 if (!context || context->uniqueID() != dti->fContextUniqueID) {
453 return nullptr; 495 return nullptr;
454 } 496 }
455 SkAutoTUnref<SkColorTable> colorTable; 497 SkAutoTUnref<SkColorTable> colorTable;
456 if (dti->fData.fColorTableCnt) { 498 if (dti->fData.fColorTableCnt) {
457 SkASSERT(dti->fData.fColorTableData); 499 SkASSERT(dti->fData.fColorTableData);
458 colorTable.reset(new SkColorTable(dti->fData.fColorTableData, dti->fData .fColorTableCnt)); 500 colorTable.reset(new SkColorTable(dti->fData.fColorTableData, dti->fData .fColorTableCnt));
459 } 501 }
460 SkASSERT(dti->fData.fMipMapLevelCount == 1); 502 int mipLevelCount = dti->fData.fMipMapLevelCount;
461 SkPixmap pixmap; 503 SkASSERT(mipLevelCount >= 1);
462 pixmap.reset(dti->fData.fInfo, dti->fData.fMipMapLevelData[0].fPixelData, 504 if (mipLevelCount == 1) {
463 dti->fData.fMipMapLevelData[0].fRowBytes, colorTable.get()); 505 SkPixmap pixmap;
464 return SkImage::MakeTextureFromPixmap(context, pixmap, budgeted); 506 pixmap.reset(dti->fData.fInfo, dti->fData.fMipMapLevelData[0].fPixelData ,
507 dti->fData.fMipMapLevelData[0].fRowBytes, colorTable.get()) ;
508 return SkImage::MakeTextureFromPixmap(context, pixmap, budgeted);
509 } else {
510 SkAutoTDeleteArray<GrMipLevel> texels(new GrMipLevel[mipLevelCount]);
511 for (int i = 0; i < mipLevelCount; i++) {
512 texels[i].fPixels = dti->fData.fMipMapLevelData[i].fPixelData;
513 texels[i].fRowBytes = dti->fData.fMipMapLevelData[i].fRowBytes;
514 }
515
516 return SkImage::MakeTextureFromMipMap(context, dti->fData.fInfo, texels. get(),
517 mipLevelCount, SkBudgeted::kYes);
518 }
465 } 519 }
466 520
467 //////////////////////////////////////////////////////////////////////////////// /////////////////// 521 //////////////////////////////////////////////////////////////////////////////// ///////////////////
468 522
469 GrTexture* GrDeepCopyTexture(GrTexture* src, SkBudgeted budgeted) { 523 GrTexture* GrDeepCopyTexture(GrTexture* src, SkBudgeted budgeted) {
470 GrContext* ctx = src->getContext(); 524 GrContext* ctx = src->getContext();
471 525
472 GrSurfaceDesc desc = src->desc(); 526 GrSurfaceDesc desc = src->desc();
473 GrTexture* dst = ctx->textureProvider()->createTexture(desc, budgeted, nullp tr, 0); 527 GrTexture* dst = ctx->textureProvider()->createTexture(desc, budgeted, nullp tr, 0);
474 if (!dst) { 528 if (!dst) {
475 return nullptr; 529 return nullptr;
476 } 530 }
477 531
478 const SkIRect srcR = SkIRect::MakeWH(desc.fWidth, desc.fHeight); 532 const SkIRect srcR = SkIRect::MakeWH(desc.fWidth, desc.fHeight);
479 const SkIPoint dstP = SkIPoint::Make(0, 0); 533 const SkIPoint dstP = SkIPoint::Make(0, 0);
480 ctx->copySurface(dst, src, srcR, dstP); 534 ctx->copySurface(dst, src, srcR, dstP);
481 ctx->flushSurfaceWrites(dst); 535 ctx->flushSurfaceWrites(dst);
482 return dst; 536 return dst;
483 } 537 }
484 538
OLDNEW
« src/image/SkImage.cpp ('K') | « src/image/SkImage.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698