Beispiel #1
0
/* Hit a few SkPicture::Analysis cases not handled elsewhere. */
static void test_analysis(skiatest::Reporter* reporter) {
    SkPictureRecorder recorder;

    SkCanvas* canvas = recorder.beginRecording(100, 100);
    {
        canvas->drawRect(SkRect::MakeWH(10, 10), SkPaint ());
    }
    SkAutoTUnref<SkPicture> picture(recorder.endRecording());
    REPORTER_ASSERT(reporter, !picture->willPlayBackBitmaps());

    canvas = recorder.beginRecording(100, 100);
    {
        SkPaint paint;
        // CreateBitmapShader is too smart for us; an empty (or 1x1) bitmap shader
        // gets optimized into a non-bitmap form, so we create a 2x2 bitmap here.
        SkBitmap bitmap;
        bitmap.allocPixels(SkImageInfo::MakeN32Premul(2, 2));
        bitmap.eraseColor(SK_ColorBLUE);
        *(bitmap.getAddr32(0, 0)) = SK_ColorGREEN;
        SkShader* shader = SkShader::CreateBitmapShader(bitmap, SkShader::kClamp_TileMode,
                                                        SkShader::kClamp_TileMode);
        paint.setShader(shader)->unref();
        REPORTER_ASSERT(reporter,
                        shader->asABitmap(NULL, NULL, NULL) == SkShader::kDefault_BitmapType);

        canvas->drawRect(SkRect::MakeWH(10, 10), paint);
    }
    picture.reset(recorder.endRecording());
    REPORTER_ASSERT(reporter, picture->willPlayBackBitmaps());
}
SkPDFShader::State::State(const SkShader& shader,
                          const SkMatrix& canvasTransform, const SkIRect& bbox)
        : fCanvasTransform(canvasTransform),
          fBBox(bbox),
          fPixelGeneration(0) {
    fInfo.fColorCount = 0;
    fInfo.fColors = NULL;
    fInfo.fColorOffsets = NULL;
    shader.getLocalMatrix(&fShaderTransform);
    fImageTileModes[0] = fImageTileModes[1] = SkShader::kClamp_TileMode;

    fType = shader.asAGradient(&fInfo);

    if (fType == SkShader::kNone_GradientType) {
        SkShader::BitmapType bitmapType;
        SkMatrix matrix;
        bitmapType = shader.asABitmap(&fImage, &matrix, fImageTileModes, NULL);
        if (bitmapType != SkShader::kDefault_BitmapType) {
            fImage.reset();
            return;
        }
        SkASSERT(matrix.isIdentity());
        fPixelGeneration = fImage.getGenerationID();
    } else {
        fColorData.set(sk_malloc_throw(
                    fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar))));
        fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get());
        fInfo.fColorOffsets =
            reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount);
        shader.asAGradient(&fInfo);
    }
}
Beispiel #3
0
SkPDFShader::State::State(const SkShader& shader,
                          const SkMatrix& canvasTransform, const SkIRect& bbox)
        : fCanvasTransform(canvasTransform),
          fBBox(bbox),
          fPixelGeneration(0) {
    fInfo.fColorCount = 0;
    fInfo.fColors = NULL;
    fInfo.fColorOffsets = NULL;
    fShaderTransform = shader.getLocalMatrix();
    fImageTileModes[0] = fImageTileModes[1] = SkShader::kClamp_TileMode;

    fType = shader.asAGradient(&fInfo);

    if (fType == SkShader::kNone_GradientType) {
        SkShader::BitmapType bitmapType;
        SkMatrix matrix;
        bitmapType = shader.asABitmap(&fImage, &matrix, fImageTileModes);
        if (bitmapType != SkShader::kDefault_BitmapType) {
            fImage.reset();
            return;
        }
        SkASSERT(matrix.isIdentity());
        fPixelGeneration = fImage.getGenerationID();
    } else {
        AllocateGradientInfoStorage();
        shader.asAGradient(&fInfo);
    }
}
Beispiel #4
0
 void addBitmapFromPaint(const SkPaint& paint) {
     SkShader* shader = paint.getShader();
     if (shader) {
         SkBitmap bm;
         if (shader->asABitmap(&bm, NULL, NULL)) {
             fPRSet->add(bm.pixelRef());
         }
     }
 }
Beispiel #5
0
SkGLDevice::TexCache* SkGLDevice::setupGLPaintShader(const SkPaint& paint) {
    SkGL::SetPaint(paint);
    
    SkShader* shader = paint.getShader();
    if (NULL == shader) {
        return NULL;
    }
    
    if (!shader->setContext(this->accessBitmap(false), paint, this->matrix())) {
        return NULL;
    }
    
    SkBitmap bitmap;
    SkMatrix matrix;
    SkShader::TileMode tileModes[2];
    if (!shader->asABitmap(&bitmap, &matrix, tileModes)) {
        return NULL;
    }
    
    bitmap.lockPixels();
    if (!bitmap.readyToDraw()) {
        return NULL;
    }
    
    // see if we've already cached the bitmap from the shader
    SkPoint max;
    GLuint name;
    TexCache* cache = SkGLDevice::LockTexCache(bitmap, &name, &max);
    // the lock has already called glBindTexture for us
    SkGL::SetTexParams(paint.isFilterBitmap(), tileModes[0], tileModes[1]);
    
    // since our texture coords will be in local space, we wack the texture
    // matrix to map them back into 0...1 before we load it
    SkMatrix localM;
    if (shader->getLocalMatrix(&localM)) {
        SkMatrix inverse;
        if (localM.invert(&inverse)) {
            matrix.preConcat(inverse);
        }
    }
    
    matrix.postScale(max.fX / bitmap.width(), max.fY / bitmap.height());
    glMatrixMode(GL_TEXTURE);
    SkGL::LoadMatrix(matrix);
    glMatrixMode(GL_MODELVIEW);
    
    // since we're going to use a shader/texture, we don't want the color,
    // just its alpha
    SkGL::SetAlpha(paint.getAlpha());
    // report that we have setup the texture
    return cache;
}
 void addBitmapFromPaint(const SkPaint& paint) {
     SkShader* shader = paint.getShader();
     if (shader) {
         SkBitmap bm;
         // Check whether the shader is a gradient in order to short-circuit
         // call to asABitmap to prevent generation of bitmaps from
         // gradient shaders, which implement asABitmap.
         if (SkShader::kNone_GradientType == shader->asAGradient(NULL) &&
             shader->asABitmap(&bm, NULL, NULL)) {
             fPRSet->add(bm.pixelRef());
         }
     }
 }
Beispiel #7
0
static bool should_draw_immediately(const SkBitmap* bitmap, const SkPaint* paint,
                                    size_t bitmapSizeThreshold) {
    if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) ||
        (bitmap->getSize() > bitmapSizeThreshold))) {
        return true;
    }
    if (paint) {
        SkShader* shader = paint->getShader();
        // Here we detect the case where the shader is an SkBitmapProcShader
        // with a gpu texture attached.  Checking this without RTTI
        // requires making the assumption that only gradient shaders
        // and SkBitmapProcShader implement asABitmap().  The following
        // code may need to be revised if that assumption is ever broken.
        if (shader && !shader->asAGradient(NULL)) {
            SkBitmap bm;
            if (shader->asABitmap(&bm, NULL, NULL) &&
                bm.getTexture()) {
                return true;
            }
        }
    }
    return false;
}
Beispiel #8
0
SkPDFShader::State::State(const SkShader& shader, const SkMatrix& canvasTransform,
                          const SkIRect& bbox, SkScalar rasterScale)
        : fCanvasTransform(canvasTransform),
          fBBox(bbox),
          fPixelGeneration(0) {
    fInfo.fColorCount = 0;
    fInfo.fColors = NULL;
    fInfo.fColorOffsets = NULL;
    fShaderTransform = shader.getLocalMatrix();
    fImageTileModes[0] = fImageTileModes[1] = SkShader::kClamp_TileMode;

    fType = shader.asAGradient(&fInfo);

    if (fType == SkShader::kNone_GradientType) {
        SkShader::BitmapType bitmapType;
        SkMatrix matrix;
        bitmapType = shader.asABitmap(&fImage, &matrix, fImageTileModes);
        if (bitmapType != SkShader::kDefault_BitmapType) {
            // Generic fallback for unsupported shaders:
            //  * allocate a bbox-sized bitmap
            //  * shade the whole area
            //  * use the result as a bitmap shader

            // bbox is in device space. While that's exactly what we want for sizing our bitmap,
            // we need to map it into shader space for adjustments (to match
            // SkPDFImageShader::Create's behavior).
            SkRect shaderRect = SkRect::Make(bbox);
            if (!inverse_transform_bbox(canvasTransform, &shaderRect)) {
                fImage.reset();
                return;
            }

            // Clamp the bitmap size to about 1M pixels
            static const SkScalar kMaxBitmapArea = 1024 * 1024;
            SkScalar bitmapArea = rasterScale * bbox.width() * rasterScale * bbox.height();
            if (bitmapArea > kMaxBitmapArea) {
                rasterScale *= SkScalarSqrt(SkScalarDiv(kMaxBitmapArea, bitmapArea));
            }

            SkISize size = SkISize::Make(SkScalarRoundToInt(rasterScale * bbox.width()),
                                         SkScalarRoundToInt(rasterScale * bbox.height()));
            SkSize scale = SkSize::Make(SkIntToScalar(size.width()) / shaderRect.width(),
                                        SkIntToScalar(size.height()) / shaderRect.height());

            fImage.allocN32Pixels(size.width(), size.height());
            fImage.eraseColor(SK_ColorTRANSPARENT);

            SkPaint p;
            p.setShader(const_cast<SkShader*>(&shader));

            SkCanvas canvas(fImage);
            canvas.scale(scale.width(), scale.height());
            canvas.translate(-shaderRect.x(), -shaderRect.y());
            canvas.drawPaint(p);

            fShaderTransform.setTranslate(shaderRect.x(), shaderRect.y());
            fShaderTransform.preScale(1 / scale.width(), 1 / scale.height());
        } else {
            SkASSERT(matrix.isIdentity());
        }
        fPixelGeneration = fImage.getGenerationID();
    } else {
        AllocateGradientInfoStorage();
        shader.asAGradient(&fInfo);
    }
}
Beispiel #9
0
void SkGLDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
                              int vertexCount, const SkPoint vertices[],
                              const SkPoint texs[], const SkColor colors[],
                              SkXfermode* xmode,
                              const uint16_t indices[], int indexCount,
                              const SkPaint& paint) {

    if (false) {
        SkRect bounds;
        SkIRect ibounds;
        
        bounds.set(vertices, vertexCount);
        bounds.round(&ibounds);
        
        SkDebugf("---- drawverts: %d pts, texs=%d colors=%d indices=%d bounds [%d %d]\n",
                 vertexCount, texs!=0, colors!=0, indexCount, ibounds.width(), ibounds.height());
    }
    
    SkGLClipIter* iter = this->updateMatrixClip();
    
    SkGL::SetPaint(paint);
    
    const SkGLVertex* glVerts;
    const SkGLVertex* glTexs = NULL;
    
#if GLSCALAR_IS_SCALAR
    glVerts = (const SkGLVertex*)vertices;
#else
    SkAutoSTMalloc<32, SkGLVertex> storage(vertexCount);
    storage.get()->setPoints(vertices, vertexCount);
    glVerts = storage.get();
#endif
    
    uint8_t* colorArray = NULL;
    if (colors) {
        colorArray = (uint8_t*)sk_malloc_throw(vertexCount*4);
        SkGL::SetRGBA(colorArray, colors, vertexCount);
    }
    SkAutoFree afca(colorArray);
    
    SkGLVertex* texArray = NULL;
    TexCache* cache = NULL;

    if (texs && paint.getShader()) {
        SkShader* shader = paint.getShader();
        
        //        if (!shader->setContext(this->accessBitmap(), paint, *draw.fMatrix)) {
        if (!shader->setContext(*draw.fBitmap, paint, *draw.fMatrix)) {
            goto DONE;
        }
        
        SkBitmap bitmap;
        SkMatrix matrix;
        SkShader::TileMode tileModes[2];
        if (shader->asABitmap(&bitmap, &matrix, tileModes)) {
            SkPoint max;
            GLuint name;
            cache = SkGLDevice::LockTexCache(bitmap, &name, &max);
            if (NULL == cache) {
                return;
            }

            matrix.postScale(max.fX / bitmap.width(), max.fY / bitmap.height());
            glMatrixMode(GL_TEXTURE);
            SkGL::LoadMatrix(matrix);
            glMatrixMode(GL_MODELVIEW);
            
#if GLSCALAR_IS_SCALAR
            glTexs = (const SkGLVertex*)texs;
#else
            texArray = (SkGLVertex*)sk_malloc_throw(vertexCount * sizeof(SkGLVertex));
            texArray->setPoints(texs, vertexCount);
            glTexs = texArray;
#endif
            
            SkGL::SetPaintAlpha(paint);
            SkGL::SetTexParams(paint.isFilterBitmap(),
                               tileModes[0], tileModes[1]);
        }
    }
DONE:
    SkAutoFree aftex(texArray);
    
    SkGL::DrawVertices(indices ? indexCount : vertexCount,
                       gVertexModeToGL[vmode],
                       glVerts, glTexs, colorArray, indices, iter);
    
    if (cache) {
        SkGLDevice::UnlockTexCache(cache);
    }
}