예제 #1
0
static void rerecord(const SkPicture& src, SkBBHFactory* bbhFactory) {
    SkPictureRecorder recorder;
    if (FLAGS_skr) {
        src.draw(recorder.EXPERIMENTAL_beginRecording(src.width(), src.height(), bbhFactory));
    } else {
        src.draw(recorder.beginRecording(src.width(), src.height(), bbhFactory));
    }
    SkAutoTUnref<SkPicture> pic(recorder.endRecording());
}
예제 #2
0
static void draw(const EXPERIMENTAL::SkPlayback& skr, const SkPicture& skp, SkCanvas* canvas) {
    if (FLAGS_skr) {
        skr.draw(canvas);
    } else {
        skp.draw(canvas);
    }
}
예제 #3
0
void ImageBuffer::copyRecordingToCanvas(GraphicsContext* paintContext, const IntRect& r) const
{
    SkCanvas* paintCanvas = paintContext->platformContext()->mCanvas;
    SkPicture* canvasRecording = context()->platformContext()->getRecordingPicture();

    SkPaint paint;
    paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
	const SkIRect& clipBounds = paintCanvas->getTotalClip().getBounds();
	SkRect rect;
	int saveCount = 0; 
	if( (clipBounds.width() > r.width() * 2 ) || (clipBounds.height() > r.height() * 2))
	{
		rect.set(r.location().x(), r.location().y(),r.width(), r.height()); 
		saveCount = paintCanvas->saveLayer(&rect, &paint);
	}
	else
		saveCount = paintCanvas->saveLayer(0, &paint);
    paintCanvas->translate(r.location().x(), r.location().y());
    // Resize to the now known viewport.
    paintCanvas->scale(r.width() / width(), r.height() / height());
    // Draw the canvas recording into the layer recording canvas.
    canvasRecording->draw(paintCanvas);
    context()->platformContext()->clearRecording();
    paintCanvas->restoreToCount(saveCount);

}
 static void draw(JNIEnv* env, jobject, jlong canvasHandle,
                         jlong pictureHandle) {
     SkCanvas* canvas = reinterpret_cast<SkCanvas*>(canvasHandle);
     SkPicture* picture = reinterpret_cast<SkPicture*>(pictureHandle);
     SkASSERT(canvas);
     SkASSERT(picture);
     picture->draw(canvas);
 }
예제 #5
0
// Extract the command ops from the input SkPicture
static void gets_ops(SkPicture& input, SkTDArray<DrawType>* ops) {
    SkDebugCanvas debugCanvas(input.width(), input.height());
    debugCanvas.setBounds(input.width(), input.height());
    input.draw(&debugCanvas);

    ops->setCount(debugCanvas.getSize());
    for (int i = 0; i < debugCanvas.getSize(); ++i) {
        (*ops)[i] = debugCanvas.getDrawCommandAt(i)->getType();
    }
}
static void testOne(const SkString& filename) {
#if DEBUG_SHOW_TEST_NAME
    SkString testName(filename);
    const char http[] = "http";
    if (testName.startsWith(http)) {
        testName.remove(0, sizeof(http) - 1);
    }
    while (testName.startsWith("_")) {
        testName.remove(0, 1);
    }
    const char dotSkp[] = ".skp";
    if (testName.endsWith(dotSkp)) {
        size_t len = testName.size();
        testName.remove(len - (sizeof(dotSkp) - 1), sizeof(dotSkp) - 1);
    }
    testName.prepend("skp");
    testName.append("1");
    strncpy(DEBUG_FILENAME_STRING, testName.c_str(), DEBUG_FILENAME_STRING_LENGTH);
#endif
    SkString path;
    make_filepath(&path, pictDir, filename);
    SkFILEStream stream(path.c_str());
    if (!stream.isValid()) {
        return;
    }
    SkPicture* pic = SkPicture::CreateFromStream(&stream, &SkImageDecoder::DecodeMemory);
    if (!pic) {
        SkDebugf("unable to decode %s\n", filename.c_str());
        return;
    }
    int width = pic->width();
    int height = pic->height();
    SkBitmap bitmap;
    bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
    bool success = bitmap.allocPixels();
    if (!success) {
        SkDebugf("unable to allocate bitmap for %s\n", filename.c_str());
        return;
    }
    SkCanvas canvas(bitmap);
    SkString pngName(filename);
    pngName.remove(pngName.size() - 3, 3);
    pngName.append("png");
    for (int i = 0; i < 2; ++i) {
        bool useOp = i ? true : false;
        canvas.setAllowSimplifyClip(useOp);
        pic->draw(&canvas);
        SkString outFile;
        make_filepath(&outFile, useOp ? outSkpClipDir : outOldClipDir, pngName);
        SkImageEncoder::EncodeFile(outFile.c_str(), bitmap, SkImageEncoder::kPNG_Type, 100);
    }
    SkDELETE(pic);
}
예제 #7
0
파일: SampleApp.cpp 프로젝트: avary/skia
void SampleWindow::afterChildren(SkCanvas* orig) {
    switch (fCanvasType) {
    case kRaster_CanvasType:
        break;
    case kPicture_CanvasType:
        if (true) {
            SkPicture* pict = new SkPicture(*fPicture);
            fPicture->unref();
            orig->drawPicture(*pict);
            pict->unref();
        } else if (true) {
            SkDynamicMemoryWStream ostream;
            fPicture->serialize(&ostream);
            fPicture->unref();

            SkMemoryStream istream(ostream.getStream(), ostream.getOffset());
            SkPicture pict(&istream);
            orig->drawPicture(pict);
        } else {
            fPicture->draw(orig);
            fPicture->unref();
        }
        fPicture = NULL;
        break;
#ifdef SK_SUPPORT_GL
    case kOpenGL_CanvasType:
        glFlush();
        delete fGLCanvas;
        fGLCanvas = NULL;
#ifdef USE_OFFSCREEN
        reverseRedAndBlue(orig->getDevice()->accessBitmap(true));
#endif
        break;
#endif
    }

//    if ((fScrollTestX | fScrollTestY) != 0)
    {
        const SkBitmap& bm = orig->getDevice()->accessBitmap(true);
        int dx = fScrollTestX * 7;
        int dy = fScrollTestY * 7;
        SkIRect r;
        SkRegion inval;

        r.set(50, 50, 50+100, 50+100);
        bm.scrollRect(&r, dx, dy, &inval);
        paint_rgn(bm, r, inval);
    }
}
예제 #8
0
// Do the commands in 'input' match the supplied pattern? Note: this is a pretty
// heavy-weight operation since we are drawing the picture into a debug canvas
// to extract the commands.
static bool check_pattern(SkPicture& input, const SkTDArray<DrawType> &pattern) {
    SkDebugCanvas debugCanvas(input.width(), input.height());
    debugCanvas.setBounds(input.width(), input.height());
    input.draw(&debugCanvas);

    if (pattern.count() != debugCanvas.getSize()) {
        return false;
    }

    for (int i = 0; i < pattern.count(); ++i) {
        if (pattern[i] != debugCanvas.getDrawCommandAt(i)->getType()) {
            return false;
        }
    }

    return true;
}
예제 #9
0
    virtual void onDraw(SkCanvas* canvas) {
        int offset = 35000;
        int extents = 1000;

        // We record a picture of huge vertical extents in which we clear the canvas to red, create
        // a 'extents' by 'extents' round rect clip at a vertical offset of 'offset', then draw
        // green into that.
        SkPicture pict;
        SkCanvas* rec = pict.beginRecording(100, offset + extents);
        rec->drawColor(0xffff0000);
        rec->save();
        SkRect r = {
            SkIntToScalar(-extents),
            SkIntToScalar(offset - extents),
            SkIntToScalar(extents),
            SkIntToScalar(offset + extents)
        };
        SkPath p;
        p.addRoundRect(r, 5, 5);
        rec->clipPath(p, SkRegion::kIntersect_Op, true);
        rec->drawColor(0xff00ff00);
        rec->restore();
        pict.endRecording();

        // Next we play that picture into another picture of the same size.
        SkPicture pict2;
        pict.draw(pict2.beginRecording(100, offset + extents));
        pict2.endRecording();

        // Finally we play the part of that second picture that should be green into the canvas.
        canvas->save();
        canvas->translate(SkIntToScalar(extents / 2),
                          SkIntToScalar(-(offset - extents / 2)));
        pict2.draw(canvas);
        canvas->restore();

        // If the image is red, we erroneously decided the clipPath was empty and didn't record
        // the green drawColor, if it's green we're all good.
    }
예제 #10
0
/**
 * Called only by render_picture().
 */
static bool render_picture_internal(const SkString& inputPath, const SkString* outputDir,
                                    sk_tools::PictureRenderer& renderer,
                                    SkBitmap** out) {
    SkString inputFilename;
    sk_tools::get_basename(&inputFilename, inputPath);
    SkString outputDirString;
    if (NULL != outputDir && outputDir->size() > 0 && !FLAGS_writeEncodedImages) {
        outputDirString.set(*outputDir);
    }

    SkFILEStream inputStream;
    inputStream.setPath(inputPath.c_str());
    if (!inputStream.isValid()) {
        SkDebugf("Could not open file %s\n", inputPath.c_str());
        return false;
    }

    SkPicture::InstallPixelRefProc proc;
    if (FLAGS_deferImageDecoding) {
        proc = &sk_tools::LazyDecodeBitmap;
    } else if (FLAGS_writeEncodedImages) {
        SkASSERT(!FLAGS_writePath.isEmpty());
        reset_image_file_base_name(inputFilename);
        proc = &write_image_to_file;
    } else {
        proc = &SkImageDecoder::DecodeMemory;
    }

    SkDebugf("deserializing... %s\n", inputPath.c_str());

    SkPicture* picture = SkPicture::CreateFromStream(&inputStream, proc);

    if (NULL == picture) {
        SkDebugf("Could not read an SkPicture from %s\n", inputPath.c_str());
        return false;
    }

    while (FLAGS_bench_record) {
        const int kRecordFlags = 0;
        SkPicture other;
        picture->draw(other.beginRecording(picture->width(), picture->height(), kRecordFlags));
        other.endRecording();
    }

    for (int i = 0; i < FLAGS_clone; ++i) {
        SkPicture* clone = picture->clone();
        SkDELETE(picture);
        picture = clone;
    }

    SkDebugf("drawing... [%i %i] %s\n", picture->width(), picture->height(),
             inputPath.c_str());

    renderer.init(picture, &outputDirString, &inputFilename, FLAGS_writeChecksumBasedFilenames);

    if (FLAGS_preprocess) {
        if (NULL != renderer.getCanvas()) {
            renderer.getCanvas()->EXPERIMENTAL_optimize(picture);
        }
    }

    renderer.setup();

    bool success = renderer.render(out);
    if (!success) {
        SkDebugf("Failed to render %s\n", inputFilename.c_str());
    }

    renderer.end();

    SkDELETE(picture);
    return success;
}
예제 #11
0
void SkRecorder::drawPicture(SkPicture& picture) {
    picture.draw(this);
}
예제 #12
0
CanvasLayer::CanvasLayer(const CanvasLayer& layer)
    : LayerAndroid(layer)
    , m_canvas(0)
    , m_bitmap(0)
    , m_gpuCanvas(0)
{
    init();
    if (!layer.m_canvas) {
        // The canvas has already been destroyed - this shouldn't happen
        ALOGW("Creating a CanvasLayer for a destroyed canvas!");
        m_visibleContentRect = IntRect();
        m_offsetFromRenderer = IntSize();
        m_texture->setHwAccelerated(false);
        return;
    }
    // We are making a copy for the UI, sync the interesting bits
    m_visibleContentRect = layer.visibleContentRect();
    m_offsetFromRenderer = layer.offsetFromRenderer();
    bool previousState = m_texture->hasValidTexture();

    if(layer.m_canvas->isUsingGpuRendering())
        return;

    ImageBuffer* imageBuffer = layer.m_canvas->buffer();
    
    if (!previousState && layer.m_dirtyCanvas.isEmpty() && imageBuffer && !(imageBuffer->drawsUsingRecording())) {
        // We were previously in software and don't have anything new to draw,
        // so stay in software
        m_bitmap = layer.bitmap();
        SkSafeRef(m_bitmap);
    } else {

        if(imageBuffer && imageBuffer->drawsUsingRecording() && !layer.m_canvas->isUsingGpuRendering())
        {
            bool canUseGpuRendering = imageBuffer->canUseGpuRendering();

            if(canUseGpuRendering && layer.m_canvas->canUseGpuRendering())
            {
                layer.m_canvas->enableGpuRendering();
                CanvasLayer::setGpuCanvasStatus(layer.uniqueId(), true);
            }
        }

        // If recording is being used
        if(imageBuffer && imageBuffer->drawsUsingRecording())
        {
            GraphicsContext* gc = imageBuffer->context();
            //SkPicture* canvasRecording = gc->platformContext()->getRecordingPicture();

            SkPicture* canvasRecording = CanvasLayer::getRecordingPicture(this);
            SkBitmap* bitmap = CanvasLayer::getRecordingBitmap(this);
            SkCanvas* canvas = CanvasLayer::getRecordingCanvas(this);

            if(canvasRecording == NULL)
                return;

            if(bitmap == NULL || bitmap->width() != canvasRecording->width()
                    || bitmap->height() != canvasRecording->height())
            {
                SkBitmap* newBitmap = new SkBitmap();
                newBitmap->setConfig(SkBitmap::kARGB_8888_Config, canvasRecording->width(), canvasRecording->height());
                newBitmap->allocPixels();
                newBitmap->eraseColor(0);
                CanvasLayer::setRecordingBitmap(newBitmap, this);
                bitmap = newBitmap;
                if(canvas != NULL)
                    canvas->setBitmapDevice(*bitmap);
            }

            if(canvas == NULL)
            {
                canvas = new SkCanvas();
                canvas->setBitmapDevice(*bitmap);
                CanvasLayer::setRecordingCanvas(canvas, this);
            }

            canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
            canvasRecording->draw(canvas);

            if (!m_texture->uploadImageBitmap(bitmap)) {
                //SLOGD("+++++++++++++++++++++ Didn't upload bitmap .. fall back to software");
                // TODO:: Fix this
            }
        }
        else
        {
            if (!m_texture->uploadImageBuffer(layer.m_canvas->buffer())) {
                // Blargh, no surface texture or ImageBuffer - fall back to software
                m_bitmap = layer.bitmap();
                SkSafeRef(m_bitmap);
                // Merge the canvas invals with the layer's invals to repaint the needed
                // tiles.
                SkRegion::Iterator iter(layer.m_dirtyCanvas);
                const IntPoint& offset = m_visibleContentRect.location();
                for (; !iter.done(); iter.next()) {
                    SkIRect diff = iter.rect();
                    diff.fLeft += offset.x();
                    diff.fRight += offset.x();
                    diff.fTop += offset.y();
                    diff.fBottom += offset.y();
                    m_dirtyRegion.op(diff, SkRegion::kUnion_Op);
                }
            }else{
                ImageBuffer* imageBuffer = layer.m_canvas->buffer();
                bool recordingCanvasEnabled = layer.m_canvas->isRecordingCanvasEnabled();

                if(recordingCanvasEnabled && imageBuffer && imageBuffer->isAnimating()){
                    SLOGD("[%s] Animation detected. Converting the HTML5 canvas buffer to a SkPicture.", __FUNCTION__);
                    imageBuffer->convertToRecording();
                }
            }//End of non-recording
        }
        if (previousState != m_texture->hasValidTexture()) {
            // Need to do a full inval of the canvas content as we are mode switching
            m_dirtyRegion.op(m_visibleContentRect.x(), m_visibleContentRect.y(),
                    m_visibleContentRect.maxX(), m_visibleContentRect.maxY(), SkRegion::kUnion_Op);
        }
    }
}
예제 #13
0
/**
 * Called only by render_picture().
 */
static bool render_picture_internal(const SkString& inputPath, const SkString* writePath,
                                    const SkString* mismatchPath,
                                    sk_tools::PictureRenderer& renderer,
                                    SkBitmap** out) {
    SkString inputFilename = SkOSPath::SkBasename(inputPath.c_str());
    SkString writePathString;
    if (NULL != writePath && writePath->size() > 0 && !FLAGS_writeEncodedImages) {
        writePathString.set(*writePath);
    }
    SkString mismatchPathString;
    if (NULL != mismatchPath && mismatchPath->size() > 0) {
        mismatchPathString.set(*mismatchPath);
    }

    SkFILEStream inputStream;
    inputStream.setPath(inputPath.c_str());
    if (!inputStream.isValid()) {
        SkDebugf("Could not open file %s\n", inputPath.c_str());
        return false;
    }

    SkPicture::InstallPixelRefProc proc;
    if (FLAGS_deferImageDecoding) {
        proc = &sk_tools::LazyDecodeBitmap;
    } else if (FLAGS_writeEncodedImages) {
        SkASSERT(!FLAGS_writePath.isEmpty());
        reset_image_file_base_name(inputFilename);
        proc = &write_image_to_file;
    } else {
        proc = &SkImageDecoder::DecodeMemory;
    }

    SkDebugf("deserializing... %s\n", inputPath.c_str());

    SkPicture* picture = SkPicture::CreateFromStream(&inputStream, proc);

    if (NULL == picture) {
        SkDebugf("Could not read an SkPicture from %s\n", inputPath.c_str());
        return false;
    }

    while (FLAGS_bench_record) {
        SkPictureRecorder recorder;
        picture->draw(recorder.beginRecording(picture->width(), picture->height(), NULL, 0));
        SkAutoTUnref<SkPicture> other(recorder.endRecording());
    }

    SkDebugf("drawing... [%i %i] %s\n", picture->width(), picture->height(),
             inputPath.c_str());

    renderer.init(picture, &writePathString, &mismatchPathString, &inputFilename,
                  FLAGS_writeChecksumBasedFilenames);

    if (FLAGS_preprocess) {
        if (NULL != renderer.getCanvas()) {
            renderer.getCanvas()->EXPERIMENTAL_optimize(renderer.getPicture());
        }
    }

    renderer.setup();
    renderer.enableWrites();

    bool success = renderer.render(out);
    if (!success) {
        SkDebugf("Failed to render %s\n", inputFilename.c_str());
    }

    renderer.end();

    SkDELETE(picture);
    return success;
}