SkPictureShader: scale down if width or height is larger than maxTextureSize
authorgen.kim <gen.kim@samsung.com>
Mon, 4 May 2015 05:36:30 +0000 (22:36 -0700)
committerCommit bot <commit-bot@chromium.org>
Mon, 4 May 2015 05:36:30 +0000 (22:36 -0700)
Grdient renders black because of failure onCreateTexture
if one of width or height is larger than maxTextureSize
with --force-gpu-rasterization.

BUG=chromium:473166

Review URL: https://codereview.chromium.org/1101513004

src/core/SkPictureShader.cpp
src/core/SkPictureShader.h

index cd2301b91b5f0f640896990cc58ed33717e43f5c..e831320a7ec38649a578a96cf70da29d60a6feb1 100644 (file)
@@ -141,7 +141,8 @@ void SkPictureShader::flatten(SkWriteBuffer& buffer) const {
     fPicture->flatten(buffer);
 }
 
-SkShader* SkPictureShader::refBitmapShader(const SkMatrix& matrix, const SkMatrix* localM) const {
+SkShader* SkPictureShader::refBitmapShader(const SkMatrix& matrix, const SkMatrix* localM,
+                                            const int maxTextureSize) const {
     SkASSERT(fPicture && !fPicture->cullRect().isEmpty());
 
     SkMatrix m;
@@ -171,6 +172,17 @@ SkShader* SkPictureShader::refBitmapShader(const SkMatrix& matrix, const SkMatri
         scaledSize.set(SkScalarMul(scaledSize.width(), clampScale),
                        SkScalarMul(scaledSize.height(), clampScale));
     }
+#if SK_SUPPORT_GPU
+    // Scale down the tile size if larger than maxTextureSize for GPU Path or it should fail on create texture
+    if (maxTextureSize) {
+        if (scaledSize.width() > maxTextureSize || scaledSize.height() > maxTextureSize) {
+            SkScalar downScale = SkScalarDiv(maxTextureSize,
+                                            SkMax32(scaledSize.width(), scaledSize.height()));
+            scaledSize.set(SkScalarMul(scaledSize.width(), downScale),
+                           SkScalarMul(scaledSize.height(), downScale));
+        }
+    }
+#endif
 
     SkISize tileSize = scaledSize.toRound();
     if (tileSize.isEmpty()) {
@@ -299,7 +311,11 @@ bool SkPictureShader::asFragmentProcessor(GrContext* context, const SkPaint& pai
                                           const SkMatrix& viewM, const SkMatrix* localMatrix,
                                           GrColor* paintColor,
                                           GrFragmentProcessor** fp) const {
-    SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(viewM, localMatrix));
+    int maxTextureSize = 0;
+    if (context) {
+        maxTextureSize = context->getMaxTextureSize();
+    }
+    SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(viewM, localMatrix, maxTextureSize));
     if (!bitmapShader) {
         return false;
     }
index c40b01b8280dbb1bee7739e79fd04c819f4061fd..3fa27b5a65ac6462d0ceae0ac379f2a7108d6b84 100644 (file)
@@ -41,7 +41,7 @@ protected:
 private:
     SkPictureShader(const SkPicture*, TileMode, TileMode, const SkMatrix*, const SkRect*);
 
-    SkShader* refBitmapShader(const SkMatrix&, const SkMatrix* localMatrix) const;
+    SkShader* refBitmapShader(const SkMatrix&, const SkMatrix* localMatrix, const int maxTextureSize = 0) const;
 
     const SkPicture* fPicture;
     SkRect           fTile;