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

Unified Diff: src/gpu/SkGr.cpp

Issue 1249543003: Creating functions for uploading a mipmapped texture. (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: Storing the max mipmap level in the texture. Created 4 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: src/gpu/SkGr.cpp
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 954bb808524243d181ed5066b6d84c5ef7b29449..43d7980d63514ad96226c394c353d3988328aad6 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -23,9 +23,12 @@
#include "SkErrorInternals.h"
#include "SkGrPixelRef.h"
#include "SkMessageBus.h"
+#include "SkMath.h"
+#include "SkMipMapLevel.h"
#include "SkPixelRef.h"
#include "SkResourceCache.h"
#include "SkTextureCompressor.h"
+#include "SkTypes.h"
#include "SkYUVPlanesCache.h"
#include "effects/GrBicubicEffect.h"
#include "effects/GrConstColorProcessor.h"
@@ -285,6 +288,97 @@ void GrInstallBitmapUniqueKeyInvalidator(const GrUniqueKey& key, SkPixelRef* pix
pixelRef->addGenIDChangeListener(new Invalidator(key));
}
+GrTexture* GrGenerateMipMapsAndUploadToTexture(GrContext* ctx, const SkBitmap& bitmap)
+{
+ GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap.info());
+ if (kIndex_8_SkColorType != bitmap.colorType() && !bitmap.readyToDraw()) {
+ GrTexture *texture = load_etc1_texture(ctx, bitmap, desc);
+ if (texture) {
+ return texture;
+ }
+ }
+
+ GrTexture *texture = create_texture_from_yuv(ctx, bitmap, desc);
+ if (texture) {
+ return texture;
+ }
+
+ SkASSERT(sizeof(int) <= sizeof(uint32_t));
+ if (bitmap.width() < 0 || bitmap.height() < 0) {
+ return nullptr;
+ }
+ const uint32_t baseWidth = static_cast<uint32_t>(bitmap.width());
+ const uint32_t baseHeight = static_cast<uint32_t>(bitmap.height());
+
+ // OpenGL's spec requires that each mipmap level have height/width equal to
+ // max(1, floor(original_height / 2^i)
+ // (or original_width) where i is the mipmap level.
+ // Continue scaling down until both axes are size 1.
+
+ const uint32_t largestAxis = SkTMax(baseWidth, baseHeight);
+ const int leadingZeros = SkCLZ(largestAxis);
+ // If the value 00011010 has 3 leading 0s then it has 5 significant bits
+ // (the bits which are not leading zeros)
+ const int significantBits = (sizeof(uint32_t) * 8) - leadingZeros;
+ // This is making the assumption that the size of a byte is 8 bits
+ // and that sizeof(uint32_t)'s implementation-defined behavior is 4.
+ if (significantBits < 0) {
+ return nullptr;
+ }
+ const int mipLevelCount = significantBits;
+
+ const bool isMipMapped = mipLevelCount > 1;
+ desc.fIsMipMapped = isMipMapped;
+
+ SkTArray<SkBitmap> mipLevelBitmaps(mipLevelCount - 1);
+ mipLevelBitmaps.push_back_n(mipLevelCount - 1);
+
+ SkTArray<SkMipMapLevel> texels(mipLevelCount);
+
+ SkAutoLockPixels alp(bitmap);
+ if (!bitmap.readyToDraw()) {
+ return nullptr;
+ }
+
+ SkMipMapLevel baseLevel(bitmap.getPixels(), bitmap.rowBytes(), baseWidth, baseHeight);
+ texels.push_back(baseLevel);
+
+ SkPaint paint;
+ paint.setFilterQuality(kMedium_SkFilterQuality);
+
+ for (int i = 1; i < mipLevelCount; i++) {
+ SkBitmap& currentMipBitmap = mipLevelBitmaps[i - 1];
+
+ uint32_t twoToTheMipLevel = 1 << i;
+ uint32_t currentMipLevelWidth = SkTMax(1u, baseWidth / twoToTheMipLevel);
+ uint32_t currentMipLevelHeight = SkTMax(1u, baseHeight / twoToTheMipLevel);
+
+ SkImageInfo info = SkImageInfo::Make(currentMipLevelWidth, currentMipLevelHeight,
+ bitmap.colorType(), bitmap.alphaType());
+ if (!currentMipBitmap.tryAllocPixels(info)) {
+ return nullptr;
+ }
+
+ SkCanvas canvas(currentMipBitmap);
+ canvas.clear(SK_ColorTRANSPARENT);
+
+ SkMatrix matrix;
+ matrix.setScale(static_cast<float>(currentMipLevelWidth) / baseWidth,
+ static_cast<float>(currentMipLevelHeight) / baseHeight);
+ canvas.save();
+ canvas.concat(matrix);
+ canvas.drawBitmap(bitmap, SkIntToScalar(0), SkIntToScalar(0), &paint);
bsalomon 2016/01/14 13:57:23 Mike pointed out to me that this will generate MIP
Chris Blume 2016/01/20 06:15:08 I talked to Mike, asking for clarification on the
+ canvas.restore();
+
+ SkMipMapLevel currentMipLevel(currentMipBitmap.getPixels(),
+ currentMipBitmap.rowBytes(),
+ currentMipLevelWidth, currentMipLevelHeight);
+ texels.push_back(currentMipLevel);
+ }
+
+ return ctx->textureProvider()->createTexture(desc, true, texels);
+}
+
GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap,
const GrTextureParams& params) {
if (bitmap.getTexture()) {

Powered by Google App Engine
This is Rietveld 408576698