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

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: Addressing CR comments. 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') | 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 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 // It contains fMipMapLevelCount elements. 342 // It contains fMipMapLevelCount elements.
342 // That means this struct's size is not known at compile-time. 343 // That means this struct's size is not known at compile-time.
343 MipMapLevelData fMipMapLevelData[1]; 344 MipMapLevelData fMipMapLevelData[1];
344 }; 345 };
345 Data fData; 346 Data fData;
346 347
347 friend class SkImage; 348 friend class SkImage;
348 }; 349 };
349 350
350 size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox y, 351 size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox y,
351 const DeferredTextureImageUsageParam s[], 352 const DeferredTextureImageUsageParam s params[],
352 int paramCnt, void* buffer) const { 353 int paramCnt, void* buffer) const {
354 bool shouldUseMipMaps = false;
355 for (int currentParamIndex = paramCnt - 1; currentParamIndex >= 0; currentPa ramIndex--) {
356 const SkMatrix& currentMatrix = params[currentParamIndex].fMatrix;
357 SkFilterQuality currentFilterQuality = params[currentParamIndex].fQualit y;
358
359 // Use mipmaps if either
360 // 1.) it is a perspective matrix, or
361 // 2.) the quality is med/high and the scale is < 1
362 if (currentMatrix.hasPerspective()) {
363 shouldUseMipMaps = true;
364 }
365 if (currentFilterQuality == kMedium_SkFilterQuality ||
366 currentFilterQuality == kHigh_SkFilterQuality) {
367 SkScalar minAxisScale = currentMatrix.getMinScale();
368 if (minAxisScale != -1.f) {
ericrk 2016/06/06 22:57:40 nit - just && this and the following if to reduce
cblume 2016/06/08 17:50:33 Done.
369 if (minAxisScale < 1.f) {
370 shouldUseMipMaps = true;
371 }
372 }
373 }
374 }
375
353 const bool fillMode = SkToBool(buffer); 376 const bool fillMode = SkToBool(buffer);
354 if (fillMode && !SkIsAlign8(reinterpret_cast<intptr_t>(buffer))) { 377 if (fillMode && !SkIsAlign8(reinterpret_cast<intptr_t>(buffer))) {
355 return 0; 378 return 0;
356 } 379 }
357 380
358 const int maxTextureSize = proxy.fCaps->maxTextureSize(); 381 const int maxTextureSize = proxy.fCaps->maxTextureSize();
359 if (width() > maxTextureSize || height() > maxTextureSize) { 382 if (width() > maxTextureSize || height() > maxTextureSize) {
360 return 0; 383 return 0;
361 } 384 }
362 385
(...skipping 21 matching lines...) Expand all
384 info = SkImageInfo::MakeN32(this->width(), this->height(), at); 407 info = SkImageInfo::MakeN32(this->width(), this->height(), at);
385 pixelSize = SkAlign8(SkAutoPixmapStorage::AllocSize(info, nullptr)); 408 pixelSize = SkAlign8(SkAutoPixmapStorage::AllocSize(info, nullptr));
386 if (fillMode) { 409 if (fillMode) {
387 pixmap.alloc(info); 410 pixmap.alloc(info);
388 if (!this->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHint)) { 411 if (!this->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHint)) {
389 return 0; 412 return 0;
390 } 413 }
391 SkASSERT(!pixmap.ctable()); 414 SkASSERT(!pixmap.ctable());
392 } 415 }
393 } 416 }
417 SkAlphaType at = this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaTyp e;
394 int mipMapLevelCount = 1; 418 int mipMapLevelCount = 1;
419 if (shouldUseMipMaps) {
420 mipMapLevelCount = SkMipMap::ComputeLevelCount(width(), height()) + 1;
ericrk 2016/06/06 22:57:40 nit: thanks for fixing this up - please add a comm
cblume 2016/06/08 17:50:33 Done.
421
422 // SkMipMap will generate
ericrk 2016/06/06 22:57:40 nit: comment isn't finished?
cblume 2016/06/08 17:50:33 Done.
423 for (int currentMipMapLevelIndex = mipMapLevelCount - 1; currentMipMapLe velIndex >= 0;
424 currentMipMapLevelIndex--) {
425 SkISize mipSize = SkMipMap::ComputeLevelSize(width(), height(), curr entMipMapLevelIndex);
426 SkImageInfo mipInfo = SkImageInfo::MakeN32(mipSize.fWidth, mipSize.f Height, at);
427 pixelSize += SkAlign8(SkAutoPixmapStorage::AllocSize(mipInfo, nullpt r));
ericrk 2016/06/06 22:57:40 This will add in the size of level 0... isn't leve
cblume 2016/06/08 17:50:33 We need both, I believe. 393/408 gets the size of
428 }
429 }
395 size_t size = 0; 430 size_t size = 0;
396 size_t dtiSize = SkAlign8(sizeof(DeferredTextureImage)); 431 size_t dtiSize = SkAlign8(sizeof(DeferredTextureImage));
397 size += dtiSize; 432 size += dtiSize;
398 size += mipMapLevelCount * sizeof(DeferredTextureImage::MipMapLevelData); 433 size += mipMapLevelCount * sizeof(DeferredTextureImage::MipMapLevelData);
399 size_t pixelOffset = size; 434 size_t pixelOffset = size;
400 size += pixelSize; 435 size += pixelSize;
401 size_t ctOffset = size; 436 size_t ctOffset = size;
402 size += ctSize; 437 size += ctSize;
403 if (!fillMode) { 438 if (!fillMode) {
404 return size; 439 return size;
(...skipping 13 matching lines...) Expand all
418 SkASSERT(info == pixmap.info()); 453 SkASSERT(info == pixmap.info());
419 size_t rowBytes = pixmap.rowBytes(); 454 size_t rowBytes = pixmap.rowBytes();
420 DeferredTextureImage* dti = new (buffer) DeferredTextureImage(); 455 DeferredTextureImage* dti = new (buffer) DeferredTextureImage();
421 dti->fContextUniqueID = proxy.fContextUniqueID; 456 dti->fContextUniqueID = proxy.fContextUniqueID;
422 dti->fData.fInfo = info; 457 dti->fData.fInfo = info;
423 dti->fData.fColorTableCnt = ctCount; 458 dti->fData.fColorTableCnt = ctCount;
424 dti->fData.fColorTableData = ct; 459 dti->fData.fColorTableData = ct;
425 dti->fData.fMipMapLevelCount = mipMapLevelCount; 460 dti->fData.fMipMapLevelCount = mipMapLevelCount;
426 dti->fData.fMipMapLevelData[0].fPixelData = pixels; 461 dti->fData.fMipMapLevelData[0].fPixelData = pixels;
427 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 // SkMipMap holds only the mipmap levels it generates.
469 // A programmer can use the data they provided to SkMipMap::Build as lev el 0.
470 // So the SkMipMap provides levels 1-x but it stores them in its own
471 // range 0-(x-1).
472 // This iterates 1-x.
473 for (int currentMipMapLevelIndex = 1; currentMipMapLevelIndex < mipMapLe velCount;
474 currentMipMapLevelIndex++) {
475 SkISize prevMipSize = SkMipMap::ComputeLevelSize(width(), height(), currentMipMapLevelIndex - 1);
476 SkImageInfo prevMipInfo = SkImageInfo::MakeN32(prevMipSize.fWidth, p revMipSize.fHeight, at);
477 mipLevelPtr += SkAlign8(SkAutoPixmapStorage::AllocSize(prevMipInfo, nullptr));
478
479 SkMipMap::Level currentMipMapLevel;
480 mipmaps->getLevel(currentMipMapLevelIndex - 1, &currentMipMapLevel);
481 memcpy(reinterpret_cast<void*>(mipLevelPtr), currentMipMapLevel.fPix map.addr(),
482 currentMipMapLevel.fPixmap.getSafeSize());
483 dti->fData.fMipMapLevelData[currentMipMapLevelIndex].fPixelData =
484 reinterpret_cast<void*>(mipLevelPtr);
485 dti->fData.fMipMapLevelData[currentMipMapLevelIndex].fRowBytes =
486 currentMipMapLevel.fPixmap.rowBytes();
487 }
488 }
428 return size; 489 return size;
429 } 490 }
430 491
431 sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, con st void* data, 492 sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, con st void* data,
432 SkBudgeted budgeted) { 493 SkBudgeted budgeted) {
433 if (!data) { 494 if (!data) {
434 return nullptr; 495 return nullptr;
435 } 496 }
436 const DeferredTextureImage* dti = reinterpret_cast<const DeferredTextureImag e*>(data); 497 const DeferredTextureImage* dti = reinterpret_cast<const DeferredTextureImag e*>(data);
437 498
438 if (!context || context->uniqueID() != dti->fContextUniqueID) { 499 if (!context || context->uniqueID() != dti->fContextUniqueID) {
439 return nullptr; 500 return nullptr;
440 } 501 }
441 SkAutoTUnref<SkColorTable> colorTable; 502 SkAutoTUnref<SkColorTable> colorTable;
442 if (dti->fData.fColorTableCnt) { 503 if (dti->fData.fColorTableCnt) {
443 SkASSERT(dti->fData.fColorTableData); 504 SkASSERT(dti->fData.fColorTableData);
444 colorTable.reset(new SkColorTable(dti->fData.fColorTableData, dti->fData .fColorTableCnt)); 505 colorTable.reset(new SkColorTable(dti->fData.fColorTableData, dti->fData .fColorTableCnt));
445 } 506 }
446 SkASSERT(dti->fData.fMipMapLevelCount == 1); 507 int mipLevelCount = dti->fData.fMipMapLevelCount;
447 SkPixmap pixmap; 508 SkASSERT(mipLevelCount >= 1);
448 pixmap.reset(dti->fData.fInfo, dti->fData.fMipMapLevelData[0].fPixelData, 509 if (mipLevelCount == 1) {
449 dti->fData.fMipMapLevelData[0].fRowBytes, colorTable.get()); 510 SkPixmap pixmap;
450 return SkImage::MakeTextureFromPixmap(context, pixmap, budgeted); 511 pixmap.reset(dti->fData.fInfo, dti->fData.fMipMapLevelData[0].fPixelData ,
512 dti->fData.fMipMapLevelData[0].fRowBytes, colorTable.get()) ;
513 return SkImage::MakeTextureFromPixmap(context, pixmap, budgeted);
514 } else {
515 SkAutoTDeleteArray<GrMipLevel> texels(new GrMipLevel[mipLevelCount]);
516 for (int i = 0; i < mipLevelCount; i++) {
517 texels[i].fPixels = dti->fData.fMipMapLevelData[i].fPixelData;
518 texels[i].fRowBytes = dti->fData.fMipMapLevelData[i].fRowBytes;
519 }
520
521 return SkImage::MakeTextureFromMipMap(context, dti->fData.fInfo, texels. get(),
522 mipLevelCount, SkBudgeted::kYes);
523 }
451 } 524 }
452 525
453 //////////////////////////////////////////////////////////////////////////////// /////////////////// 526 //////////////////////////////////////////////////////////////////////////////// ///////////////////
454 527
455 GrTexture* GrDeepCopyTexture(GrTexture* src, SkBudgeted budgeted) { 528 GrTexture* GrDeepCopyTexture(GrTexture* src, SkBudgeted budgeted) {
456 GrContext* ctx = src->getContext(); 529 GrContext* ctx = src->getContext();
457 530
458 GrSurfaceDesc desc = src->desc(); 531 GrSurfaceDesc desc = src->desc();
459 GrTexture* dst = ctx->textureProvider()->createTexture(desc, budgeted, nullp tr, 0); 532 GrTexture* dst = ctx->textureProvider()->createTexture(desc, budgeted, nullp tr, 0);
460 if (!dst) { 533 if (!dst) {
(...skipping 13 matching lines...) Expand all
474 if (!ctx) { 547 if (!ctx) {
475 return nullptr; 548 return nullptr;
476 } 549 }
477 SkAutoTUnref<GrTexture> texture(GrUploadMipMapToTexture(ctx, info, texels, m ipLevelCount)); 550 SkAutoTUnref<GrTexture> texture(GrUploadMipMapToTexture(ctx, info, texels, m ipLevelCount));
478 if (!texture) { 551 if (!texture) {
479 return nullptr; 552 return nullptr;
480 } 553 }
481 return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNew ImageUniqueID, 554 return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNew ImageUniqueID,
482 info.alphaType(), texture, budgeted); 555 info.alphaType(), texture, budgeted);
483 } 556 }
OLDNEW
« no previous file with comments | « src/image/SkImage.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698