示例#1
0
sk_sp<SkSpecialImage> SkBitmapDevice::makeSpecial(const SkBitmap& bitmap) {
    return SkSpecialImage::MakeFromRaster(bitmap.bounds(), bitmap);
}
示例#2
0
static bool check_output_bitmap(const SkBitmap& bitmap, uint32_t expectedID) {
    SkASSERT(bitmap.getGenerationID() == expectedID);
    SkASSERT(bitmap.isImmutable());
    SkASSERT(bitmap.getPixels());
    return true;
}
示例#3
0
static void test_allocpixels(skiatest::Reporter* reporter) {
    const int width = 10;
    const int height = 10;
    const SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
    const size_t explicitRowBytes = info.minRowBytes() + 24;

    SkBitmap bm;
    bm.setInfo(info);
    REPORTER_ASSERT(reporter, info.minRowBytes() == bm.rowBytes());
    bm.allocPixels();
    REPORTER_ASSERT(reporter, info.minRowBytes() == bm.rowBytes());
    bm.reset();
    bm.allocPixels(info);
    REPORTER_ASSERT(reporter, info.minRowBytes() == bm.rowBytes());

    bm.setInfo(info, explicitRowBytes);
    REPORTER_ASSERT(reporter, explicitRowBytes == bm.rowBytes());
    bm.allocPixels();
    REPORTER_ASSERT(reporter, explicitRowBytes == bm.rowBytes());
    bm.reset();
    bm.allocPixels(info, explicitRowBytes);
    REPORTER_ASSERT(reporter, explicitRowBytes == bm.rowBytes());

    bm.reset();
    bm.setInfo(info, 0);
    REPORTER_ASSERT(reporter, info.minRowBytes() == bm.rowBytes());
    bm.reset();
    bm.allocPixels(info, 0);
    REPORTER_ASSERT(reporter, info.minRowBytes() == bm.rowBytes());

    bm.reset();
    bool success = bm.setInfo(info, info.minRowBytes() - 1);   // invalid for 32bit
    REPORTER_ASSERT(reporter, !success);
    REPORTER_ASSERT(reporter, bm.isNull());
}
示例#4
0
EXPORT void benchmark(const char* url, int reloadCount, int width, int height) {
    ScriptController::initializeThreading();

    // Setting this allows data: urls to load from a local file.
    SecurityOrigin::setLocalLoadPolicy(SecurityOrigin::AllowLocalLoadsForAll);

    // Create the fake JNIEnv and JavaVM
    InitializeJavaVM();

    // The real function is private to libwebcore but we know what it does.
    notifyHistoryItemChanged = historyItemChanged;

    // Implement the shared timer callback
    MyJavaSharedClient client;
    JavaSharedClient::SetTimerClient(&client);
    JavaSharedClient::SetCookieClient(&client);

    // Create the page with all the various clients
    ChromeClientAndroid* chrome = new ChromeClientAndroid;
    EditorClientAndroid* editor = new EditorClientAndroid;
    DeviceMotionClientAndroid* deviceMotion = new DeviceMotionClientAndroid;
    DeviceOrientationClientAndroid* deviceOrientation = new DeviceOrientationClientAndroid;
    WebCore::Page::PageClients pageClients;
    pageClients.chromeClient = chrome;
    pageClients.contextMenuClient = new ContextMenuClientAndroid;
    pageClients.editorClient = editor;
    pageClients.dragClient = new DragClientAndroid;
    pageClients.inspectorClient = new InspectorClientAndroid;
    pageClients.deviceMotionClient = deviceMotion;
    pageClients.deviceOrientationClient = deviceOrientation;
    WebCore::Page* page = new WebCore::Page(pageClients);
    editor->setPage(page);

    // Create MyWebFrame that intercepts network requests
    MyWebFrame* webFrame = new MyWebFrame(page);
    webFrame->setUserAgent("Performance testing"); // needs to be non-empty
    chrome->setWebFrame(webFrame);
    // ChromeClientAndroid maintains the reference.
    Release(webFrame);

    // Create the Frame and the FrameLoaderClient
    FrameLoaderClientAndroid* loader = new FrameLoaderClientAndroid(webFrame);
    RefPtr<Frame> frame = Frame::create(page, NULL, loader);
    loader->setFrame(frame.get());

    // Build our View system, resize it to the given dimensions and release our
    // references. Note: We keep a referenec to frameView so we can layout and
    // draw later without risk of it being deleted.
    WebViewCore* webViewCore = new WebViewCore(JSC::Bindings::getJNIEnv(),
            MY_JOBJECT, frame.get());
    RefPtr<FrameView> frameView = FrameView::create(frame.get());
    WebFrameView* webFrameView = new WebFrameView(frameView.get(), webViewCore);
    frame->setView(frameView);
    frameView->resize(width, height);
    Release(webViewCore);
    Release(webFrameView);

    // Initialize the frame and turn of low-bandwidth display (it fails an
    // assertion in the Cache code)
    frame->init();
    frame->selection()->setFocused(true);
    frame->page()->focusController()->setFocused(true);

    deviceMotion->setWebViewCore(webViewCore);
    deviceOrientation->setWebViewCore(webViewCore);

    // Set all the default settings the Browser normally uses.
    Settings* s = frame->settings();
#ifdef ANDROID_LAYOUT
    s->setLayoutAlgorithm(Settings::kLayoutNormal); // Normal layout for now
#endif
    s->setStandardFontFamily("sans-serif");
    s->setFixedFontFamily("monospace");
    s->setSansSerifFontFamily("sans-serif");
    s->setSerifFontFamily("serif");
    s->setCursiveFontFamily("cursive");
    s->setFantasyFontFamily("fantasy");
    s->setMinimumFontSize(8);
    s->setMinimumLogicalFontSize(8);
    s->setDefaultFontSize(16);
    s->setDefaultFixedFontSize(13);
    s->setLoadsImagesAutomatically(true);
    s->setJavaScriptEnabled(true);
    s->setDefaultTextEncodingName("latin1");
    s->setPluginsEnabled(false);
    s->setShrinksStandaloneImagesToFit(false);
#ifdef ANDROID_LAYOUT
    s->setUseWideViewport(false);
#endif

    // Finally, load the actual data
    ResourceRequest req(url);
    frame->loader()->load(req, false);

    do {
        // Layout the page and service the timer
        frame->view()->layout();
        while (client.m_hasTimer) {
            client.m_func();
            JavaSharedClient::ServiceFunctionPtrQueue();
        }
        JavaSharedClient::ServiceFunctionPtrQueue();

        // Layout more if needed.
        while (frame->view()->needsLayout())
            frame->view()->layout();
        JavaSharedClient::ServiceFunctionPtrQueue();

        if (reloadCount)
            frame->loader()->reload(true);
    } while (reloadCount--);

    // Draw into an offscreen bitmap
    SkBitmap bmp;
    bmp.setConfig(SkBitmap::kARGB_8888_Config, width, height);
    bmp.allocPixels();
    SkCanvas canvas(bmp);
    PlatformGraphicsContext ctx(&canvas);
    GraphicsContext gc(&ctx);
    frame->view()->paintContents(&gc, IntRect(0, 0, width, height));

    // Write the bitmap to the sdcard
    SkImageEncoder* enc = SkImageEncoder::Create(SkImageEncoder::kPNG_Type);
    enc->encodeFile("/sdcard/webcore_test.png", bmp, 100);
    delete enc;

    // Tear down the world.
    frame->loader()->detachFromParent();
    delete page;
}
PassRefPtr<ImageData> getImageData(const IntRect& rect, const SkBitmap& bitmap, 
                                   const IntSize& size)
{
    RefPtr<ImageData> result = ImageData::create(rect.width(), rect.height());

    if (bitmap.config() == SkBitmap::kNo_Config) {
        // This is an empty SkBitmap that could not be configured.
        ASSERT(!size.width() || !size.height());
        return result;
    }

    unsigned char* data = result->data()->data()->data();

    if (rect.x() < 0 || rect.y() < 0 ||
        (rect.x() + rect.width()) > size.width() ||
        (rect.y() + rect.height()) > size.height())
        memset(data, 0, result->data()->length());

    int originX = rect.x();
    int destX = 0;
    if (originX < 0) {
        destX = -originX;
        originX = 0;
    }
    int endX = rect.x() + rect.width();
    if (endX > size.width())
        endX = size.width();
    int numColumns = endX - originX;

    int originY = rect.y();
    int destY = 0;
    if (originY < 0) {
        destY = -originY;
        originY = 0;
    }
    int endY = rect.y() + rect.height();
    if (endY > size.height())
        endY = size.height();
    int numRows = endY - originY;

    ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config);
    SkAutoLockPixels bitmapLock(bitmap);

    unsigned destBytesPerRow = 4 * rect.width();
    unsigned char* destRow = data + destY * destBytesPerRow + destX * 4;

    for (int y = 0; y < numRows; ++y) {
        uint32_t* srcRow = bitmap.getAddr32(originX, originY + y);
        for (int x = 0; x < numColumns; ++x) {
            unsigned char* destPixel = &destRow[x * 4];
            if (multiplied == Unmultiplied) {
                SkColor color = srcRow[x];
                unsigned a = SkColorGetA(color);
                destPixel[0] = a ? SkColorGetR(color) * 255 / a : 0;
                destPixel[1] = a ? SkColorGetG(color) * 255 / a : 0;
                destPixel[2] = a ? SkColorGetB(color) * 255 / a : 0;
                destPixel[3] = a;
            } else {
                // Input and output are both pre-multiplied, we just need to re-arrange the
                // bytes from the bitmap format to RGBA.
                destPixel[0] = SkGetPackedR32(srcRow[x]);
                destPixel[1] = SkGetPackedG32(srcRow[x]);
                destPixel[2] = SkGetPackedB32(srcRow[x]);
                destPixel[3] = SkGetPackedA32(srcRow[x]);
            }
        }
        destRow += destBytesPerRow;
    }

    return result;
}
示例#6
0
文件: surface.cpp 项目: LuckJC/pro-mk
status_t s3d_camera_test(void)
{
 	printf("[Unit Test] SurfaceFlinger 3D display test !\n\n");

    sp<SurfaceComposerClient> client;    
    //sp<SurfaceControl>        u;
    //sp<SurfaceControl>        c;
    sp<Surface>               s;
    Surface::SurfaceInfo      i;
    SkBitmap                  sbs;
    SkBitmap                  cam;

    // ready the png image file
    if (false == SkImageDecoder::DecodeFile("/data/3D_Camera_SBS.png", &sbs) ||
        false == SkImageDecoder::DecodeFile("/data/camera.png", &cam)) {
        printf("fail load file");
        return INVALID_OPERATION;
    }

    // create layer env
    client = new SurfaceComposerClient();
    printf("screen (w, h) = (%d, %d)\n\n",
        (int)client->getDisplayWidth(0), (int)client->getDisplayHeight(0));

    // test set to side by side mode, and pull to topest layer in transaction
    printf("*** camera test ...\n");

    u = client->createSurface(String8("test-ui"), 0, DRAW_FHD_W, DRAW_FHD_H, PIXEL_FORMAT_BGRA_8888);
    c = client->createSurface(String8("test-camera"), 0, DRAW_FHD_W, DRAW_FHD_H, PIXEL_FORMAT_RGBX_8888);
    
    client->openGlobalTransaction();
    {
        u->setLayer(210000);
        c->setLayer(200000);
    }
	client->closeGlobalTransaction();

    ANativeWindow       *w;                                        // fill camera surface
    ANativeWindowBuffer *buf;
    void                *ptr;
    const Rect          rect0(544, 960);
    const Rect          rect1(960, 540);

    s = u->getSurface();    // fill ui surface
    s->lock(&i);
    {        
        printf("lock ui, i.s=%d, i.h=%d\n",i.s, i.h);
        memset(i.bits, 0, i.s * i.h * 4);
        memcpy(i.bits, cam.getPixels(), 544 * 960 * 4);//buffer stride is bigger then ...
    }
    s->unlockAndPost();


    s = c->getSurface();
    w = s.get();
    native_window_api_connect(w, NATIVE_WINDOW_API_CAMERA);
    native_window_set_buffers_dimensions(w, 960, 540);
    native_window_set_buffers_format(w, HAL_PIXEL_FORMAT_RGBX_8888);
    native_window_set_usage(w, GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_S3D_TOP_AND_BOTTOM);
    native_window_set_scaling_mode(w, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
    native_window_set_buffers_transform(w, HAL_TRANSFORM_ROT_90);

    w->dequeueBuffer(w, &buf);
    GraphicBufferMapper::getInstance().lock(buf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, rect1, &ptr);
    {
        memcpy(ptr, sbs.getPixels(), 960 * 540 * 4);
    }
    GraphicBufferMapper::getInstance().unlock(buf->handle);    // inlock to return buffer
    w->queueBuffer(w, buf);                                    // queue to display


    uint8_t j = 0x80;

    client->openGlobalTransaction();
    {
        u->setAlpha(j);
    }
    client->closeGlobalTransaction();

    sleep(1);

    client->dispose();
    return NO_ERROR;   
}
示例#7
0
static size_t pixel_count(const SkBitmap& bm) {
    return SkToSizeT(bm.width()) * SkToSizeT(bm.height());
}
static void testBitmapCache_discarded_bitmap(skiatest::Reporter* reporter, SkResourceCache* cache,
                                             SkResourceCache::DiscardableFactory factory) {
    SkBitmap::Allocator* allocator = cache->allocator();
    const SkColorType testTypes[] = {
        kAlpha_8_SkColorType,
        kRGB_565_SkColorType,
        kRGBA_8888_SkColorType,
        kBGRA_8888_SkColorType,
        kIndex_8_SkColorType,
        kGray_8_SkColorType
    };
    for (const SkColorType testType : testTypes) {
        SkBitmap cachedBitmap;
        make_bitmap(&cachedBitmap, SkImageInfo::Make(5, 5, testType, kPremul_SkAlphaType),
                    allocator);
        cachedBitmap.setImmutable();
        cachedBitmap.unlockPixels();

        SkBitmap bm;
        SkIRect rect = SkIRect::MakeWH(5, 5);

        // Add a bitmap to the cache.
        REPORTER_ASSERT(reporter, SkBitmapCache::Add(cachedBitmap.pixelRef(), rect, cachedBitmap,
                                                     cache));
        REPORTER_ASSERT(reporter, SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm,
                                                      cache));

        // Finding more than once works fine.
        REPORTER_ASSERT(reporter, SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm,
                                                      cache));
        bm.unlockPixels();

        // Drop the pixels in the bitmap.
        if (factory) {
            REPORTER_ASSERT(reporter, gPool->getRAMUsed() > 0);
            gPool->dumpPool();

            // The bitmap is not in the cache since it has been dropped.
            REPORTER_ASSERT(reporter, !SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect,
                                                           &bm, cache));
        }

        make_bitmap(&cachedBitmap, SkImageInfo::Make(5, 5, testType, kPremul_SkAlphaType),
                    allocator);
        cachedBitmap.setImmutable();
        cachedBitmap.unlockPixels();

        // We can add the bitmap back to the cache and find it again.
        REPORTER_ASSERT(reporter, SkBitmapCache::Add(cachedBitmap.pixelRef(), rect, cachedBitmap,
                                                     cache));
        REPORTER_ASSERT(reporter, SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm,
                                                      cache));
    }
    test_mipmapcache(reporter, cache);
    test_bitmap_notify(reporter, cache);
    test_mipmap_notify(reporter, cache);
}
// FIXME:  This should be refactored to SkSingleInputImageFilter for
// use by other filters.  For now, we assume the input is always
// premultiplied and unpremultiply it
static SkBitmap unpremultiplyBitmap(const SkBitmap& src)
{
    SkAutoLockPixels alp(src);
    if (!src.getPixels()) {
        return SkBitmap();
    }
    SkBitmap result;
    result.setConfig(src.config(), src.width(), src.height());
    result.allocPixels();
    if (!result.getPixels()) {
        return SkBitmap();
    }
    for (int y = 0; y < src.height(); ++y) {
        const uint32_t* srcRow = src.getAddr32(0, y);
        uint32_t* dstRow = result.getAddr32(0, y);
        for (int x = 0; x < src.width(); ++x) {
            dstRow[x] = SkUnPreMultiply::PMColorToColor(srcRow[x]);
        }
    }
    return result;
}
示例#10
0
SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap, const SkSurfaceProps& surfaceProps)
    : INHERITED(surfaceProps)
    , fBitmap(bitmap) {
    SkASSERT(valid_for_bitmap_device(bitmap.info(), nullptr));
}
示例#11
0
/**
 * Render the SKP file(s) within inputPath, writing their bitmap images into outputDir.
 *
 * @param inputPath path to an individual SKP file, or a directory of SKP files
 * @param outputDir if not NULL, write the image(s) generated into this directory
 * @param renderer PictureRenderer to use to render the SKPs
 * @param jsonSummaryPtr if not NULL, add the image(s) generated to this summary
 */
static bool render_picture(const SkString& inputPath, const SkString* outputDir,
                           sk_tools::PictureRenderer& renderer,
                           sk_tools::ImageResultsSummary *jsonSummaryPtr) {
    int diffs[256] = {0};
    SkBitmap* bitmap = NULL;
    renderer.setJsonSummaryPtr(jsonSummaryPtr);
    bool success = render_picture_internal(inputPath,
        FLAGS_writeWholeImage ? NULL : outputDir,
        renderer,
        FLAGS_validate || FLAGS_writeWholeImage ? &bitmap : NULL);

    if (!success || ((FLAGS_validate || FLAGS_writeWholeImage) && bitmap == NULL)) {
        SkDebugf("Failed to draw the picture.\n");
        SkDELETE(bitmap);
        return false;
    }

    if (FLAGS_validate) {
        SkBitmap* referenceBitmap = NULL;
        sk_tools::PictureRenderer* referenceRenderer;
        // If the renderer uses a BBoxHierarchy, then the reference renderer
        // will be the same renderer, without the bbh.
        AutoRestoreBbhType arbbh;
        if (sk_tools::PictureRenderer::kNone_BBoxHierarchyType !=
            renderer.getBBoxHierarchyType()) {
            referenceRenderer = &renderer;
            referenceRenderer->ref();  // to match auto unref below
            arbbh.set(referenceRenderer, sk_tools::PictureRenderer::kNone_BBoxHierarchyType);
        } else {
            referenceRenderer = SkNEW(sk_tools::SimplePictureRenderer);
        }
        SkAutoTUnref<sk_tools::PictureRenderer> aurReferenceRenderer(referenceRenderer);

        success = render_picture_internal(inputPath, NULL, *referenceRenderer,
                                          &referenceBitmap);

        if (!success || NULL == referenceBitmap || NULL == referenceBitmap->getPixels()) {
            SkDebugf("Failed to draw the reference picture.\n");
            SkDELETE(bitmap);
            SkDELETE(referenceBitmap);
            return false;
        }

        if (success && (bitmap->width() != referenceBitmap->width())) {
            SkDebugf("Expected image width: %i, actual image width %i.\n",
                     referenceBitmap->width(), bitmap->width());
            SkDELETE(bitmap);
            SkDELETE(referenceBitmap);
            return false;
        }
        if (success && (bitmap->height() != referenceBitmap->height())) {
            SkDebugf("Expected image height: %i, actual image height %i",
                     referenceBitmap->height(), bitmap->height());
            SkDELETE(bitmap);
            SkDELETE(referenceBitmap);
            return false;
        }

        for (int y = 0; success && y < bitmap->height(); y++) {
            for (int x = 0; success && x < bitmap->width(); x++) {
                int diff = MaxByteDiff(*referenceBitmap->getAddr32(x, y),
                                       *bitmap->getAddr32(x, y));
                SkASSERT(diff >= 0 && diff <= 255);
                diffs[diff]++;

                if (diff > FLAGS_maxComponentDiff) {
                    SkDebugf("Expected pixel at (%i %i) exceedds maximum "
                                 "component diff of %i: 0x%x, actual 0x%x\n",
                             x, y, FLAGS_maxComponentDiff,
                             *referenceBitmap->getAddr32(x, y),
                             *bitmap->getAddr32(x, y));
                    SkDELETE(bitmap);
                    SkDELETE(referenceBitmap);
                    return false;
                }
            }
        }
        SkDELETE(referenceBitmap);

        for (int i = 1; i <= 255; ++i) {
            if(diffs[i] > 0) {
                SkDebugf("Number of pixels with max diff of %i is %i\n", i, diffs[i]);
            }
        }
    }

    if (FLAGS_writeWholeImage) {
        sk_tools::force_all_opaque(*bitmap);

        // TODO(epoger): It would be better for the filename (without outputDir) to be passed in
        // here, and used both for the checksum file and writing into outputDir.
        SkString inputFilename, outputPath;
        sk_tools::get_basename(&inputFilename, inputPath);
        sk_tools::make_filepath(&outputPath, *outputDir, inputFilename);
        sk_tools::replace_char(&outputPath, '.', '_');
        outputPath.append(".png");

        if (NULL != jsonSummaryPtr) {
            SkString outputFileBasename;
            sk_tools::get_basename(&outputFileBasename, outputPath);
            jsonSummaryPtr->add(inputFilename.c_str(), outputFileBasename.c_str(), *bitmap);
        }

        if (NULL != outputDir) {
            if (!SkImageEncoder::EncodeFile(outputPath.c_str(), *bitmap,
                                            SkImageEncoder::kPNG_Type, 100)) {
                SkDebugf("Failed to draw the picture.\n");
                success = false;
            }
        }
    }
    SkDELETE(bitmap);

    return success;
}
示例#12
0
SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap)
    : INHERITED(SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType))
    , fBitmap(bitmap) {
    SkASSERT(valid_for_bitmap_device(bitmap.info(), nullptr));
}
示例#13
0
void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
                                    const SkRect* src, const SkRect& dst,
                                    const SkPaint& paint, SkCanvas::SrcRectConstraint constraint) {
    SkMatrix    matrix;
    SkRect      bitmapBounds, tmpSrc, tmpDst;
    SkBitmap    tmpBitmap;

    bitmapBounds.isetWH(bitmap.width(), bitmap.height());

    // Compute matrix from the two rectangles
    if (src) {
        tmpSrc = *src;
    } else {
        tmpSrc = bitmapBounds;
    }
    matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);

    const SkRect* dstPtr = &dst;
    const SkBitmap* bitmapPtr = &bitmap;

    // clip the tmpSrc to the bounds of the bitmap, and recompute dstRect if
    // needed (if the src was clipped). No check needed if src==null.
    if (src) {
        if (!bitmapBounds.contains(*src)) {
            if (!tmpSrc.intersect(bitmapBounds)) {
                return; // nothing to draw
            }
            // recompute dst, based on the smaller tmpSrc
            matrix.mapRect(&tmpDst, tmpSrc);
            dstPtr = &tmpDst;
        }

        // since we may need to clamp to the borders of the src rect within
        // the bitmap, we extract a subset.
        const SkIRect srcIR = tmpSrc.roundOut();
        if(bitmap.pixelRef()->getTexture()) {
            // Accelerated source canvas, don't use extractSubset but readPixels to get the subset.
            // This way, the pixels are copied in CPU memory instead of GPU memory.
            bitmap.pixelRef()->readPixels(&tmpBitmap, &srcIR);
        } else {
            if (!bitmap.extractSubset(&tmpBitmap, srcIR)) {
                return;
            }
        }
        bitmapPtr = &tmpBitmap;

        // Since we did an extract, we need to adjust the matrix accordingly
        SkScalar dx = 0, dy = 0;
        if (srcIR.fLeft > 0) {
            dx = SkIntToScalar(srcIR.fLeft);
        }
        if (srcIR.fTop > 0) {
            dy = SkIntToScalar(srcIR.fTop);
        }
        if (dx || dy) {
            matrix.preTranslate(dx, dy);
        }

        SkRect extractedBitmapBounds;
        extractedBitmapBounds.isetWH(bitmapPtr->width(), bitmapPtr->height());
        if (extractedBitmapBounds == tmpSrc) {
            // no fractional part in src, we can just call drawBitmap
            goto USE_DRAWBITMAP;
        }
    } else {
        USE_DRAWBITMAP:
        // We can go faster by just calling drawBitmap, which will concat the
        // matrix with the CTM, and try to call drawSprite if it can. If not,
        // it will make a shader and call drawRect, as we do below.
        draw.drawBitmap(*bitmapPtr, matrix, dstPtr, paint);
        return;
    }

    // construct a shader, so we can call drawRect with the dst
    SkShader* s = SkShader::CreateBitmapShader(*bitmapPtr,
                                               SkShader::kClamp_TileMode,
                                               SkShader::kClamp_TileMode,
                                               &matrix);
    if (nullptr == s) {
        return;
    }

    SkPaint paintWithShader(paint);
    paintWithShader.setStyle(SkPaint::kFill_Style);
    paintWithShader.setShader(s)->unref();

    // Call ourself, in case the subclass wanted to share this setup code
    // but handle the drawRect code themselves.
    this->drawRect(draw, *dstPtr, paintWithShader);
}
示例#14
0
void SkBitmapDevice::replaceBitmapBackendForRasterSurface(const SkBitmap& bm) {
    SkASSERT(bm.width() == fBitmap.width());
    SkASSERT(bm.height() == fBitmap.height());
    fBitmap = bm;   // intent is to use bm's pixelRef (and rowbytes/config)
    fBitmap.lockPixels();
}
LayerAndroid* deserializeLayer(SkStream* stream)
{
    int type = stream->readU8();
    if (type == LTNone)
        return 0;
    // Cast is to disambiguate between ctors.
    LayerAndroid *layer;
    if (type == LTLayerAndroid)
        layer = new LayerAndroid((RenderLayer*) 0);
    else if (type == LTScrollableLayerAndroid)
        layer = new ScrollableLayerAndroid((RenderLayer*) 0);
    else {
        XLOG("Unexpected layer type: %d, aborting!", type);
        return 0;
    }

    // Layer fields
    layer->setShouldInheritFromRootTransform(stream->readBool());
    layer->setOpacity(stream->readScalar());
    layer->setSize(stream->readScalar(), stream->readScalar());
    layer->setPosition(stream->readScalar(), stream->readScalar());
    layer->setAnchorPoint(stream->readScalar(), stream->readScalar());
    layer->setMatrix(readMatrix(stream));
    layer->setChildrenMatrix(readMatrix(stream));

    // LayerAndroid fields
    layer->m_haveClip = stream->readBool();
    layer->m_isFixed = stream->readBool();
    layer->m_backgroundColorSet = stream->readBool();
    layer->m_isIframe = stream->readBool();
    layer->m_fixedLeft = readSkLength(stream);
    layer->m_fixedTop = readSkLength(stream);
    layer->m_fixedRight = readSkLength(stream);
    layer->m_fixedBottom = readSkLength(stream);
    layer->m_fixedMarginLeft = readSkLength(stream);
    layer->m_fixedMarginTop = readSkLength(stream);
    layer->m_fixedMarginRight = readSkLength(stream);
    layer->m_fixedMarginBottom = readSkLength(stream);
    layer->m_fixedRect = readSkRect(stream);
    layer->m_renderLayerPos.setX(stream->readS32());
    layer->m_renderLayerPos.setY(stream->readS32());
    layer->m_backfaceVisibility = stream->readBool();
    layer->m_visible = stream->readBool();
    layer->m_backgroundColor = stream->readU32();
    layer->m_preserves3D = stream->readBool();
    layer->m_anchorPointZ = stream->readScalar();
    layer->m_drawOpacity = stream->readScalar();
    bool hasContentsImage = stream->readBool();
    if (hasContentsImage) {
        int size = stream->readU32();
        SkAutoMalloc storage(size);
        stream->read(storage.get(), size);
        SkFlattenableReadBuffer buffer(storage.get(), size);
        SkBitmap contentsImage;
        contentsImage.unflatten(buffer);
        SkBitmapRef* imageRef = new SkBitmapRef(contentsImage);
        layer->setContentsImage(imageRef);
        delete imageRef;
    }
    bool hasRecordingPicture = stream->readBool();
    if (hasRecordingPicture) {
        layer->m_recordingPicture = new SkPicture(stream);
    }
    int animationCount = stream->readU32(); // TODO: Support (maybe?)
    readTransformationMatrix(stream, layer->m_transform);
    readTransformationMatrix(stream, layer->m_childrenTransform);
    if (type == LTScrollableLayerAndroid) {
        ScrollableLayerAndroid* scrollableLayer =
                static_cast<ScrollableLayerAndroid*>(layer);
        scrollableLayer->m_scrollLimits.set(
                stream->readScalar(),
                stream->readScalar(),
                stream->readScalar(),
                stream->readScalar());
    }
    int childCount = stream->readU32();
    for (int i = 0; i < childCount; i++) {
        LayerAndroid *childLayer = deserializeLayer(stream);
        if (childLayer)
            layer->addChild(childLayer);
    }
    layer->needsRepaint();
    XLOG("Created layer with id %d", layer->uniqueId());
    return layer;
}
示例#16
0
bool SkMatrixConvolutionImageFilter::onFilterImage(Proxy* proxy,
                                                   const SkBitmap& source,
                                                   const SkMatrix& matrix,
                                                   SkBitmap* result,
                                                   SkIPoint* loc) {
    SkBitmap src = this->getInputResult(proxy, source, matrix, loc);
    if (src.config() != SkBitmap::kARGB_8888_Config) {
        return false;
    }

    if (!fConvolveAlpha && !src.isOpaque()) {
        src = unpremultiplyBitmap(src);
    }

    SkAutoLockPixels alp(src);
    if (!src.getPixels()) {
        return false;
    }

    result->setConfig(src.config(), src.width(), src.height());
    result->allocPixels();

    SkIRect interior = SkIRect::MakeXYWH(fTarget.fX, fTarget.fY,
                                         src.width() - fKernelSize.fWidth + 1,
                                         src.height() - fKernelSize.fHeight + 1);
    SkIRect top = SkIRect::MakeWH(src.width(), fTarget.fY);
    SkIRect bottom = SkIRect::MakeLTRB(0, interior.bottom(),
                                       src.width(), src.height());
    SkIRect left = SkIRect::MakeXYWH(0, interior.top(),
                                     fTarget.fX, interior.height());
    SkIRect right = SkIRect::MakeLTRB(interior.right(), interior.top(),
                                      src.width(), interior.bottom());
    filterBorderPixels(src, result, top);
    filterBorderPixels(src, result, left);
    filterInteriorPixels(src, result, interior);
    filterBorderPixels(src, result, right);
    filterBorderPixels(src, result, bottom);
    return true;
}
示例#17
0
文件: surface.cpp 项目: LuckJC/pro-mk
status_t s3d_image_sbs_test(void)
{
	printf("[Unit Test] SurfaceFlinger 3D display test !\n\n");

    sp<SurfaceComposerClient> client;    
    //sp<SurfaceControl>        c;
    sp<Surface>               s;
    Surface::SurfaceInfo      i;
    SkBitmap                  sbs;

    // ready the png image file
    if (false == SkImageDecoder::DecodeFile("/data/3D_SBS.png", &sbs)) {
        printf("fail load file");
        return INVALID_OPERATION;
    }

    // create layer env
    client = new SurfaceComposerClient();
    printf("screen (w, h) = (%d, %d)\n\n",
        (int)client->getDisplayWidth(0), (int)client->getDisplayHeight(0));



    // test set to side by side mode, and pull to topest layer in transaction
    printf("*** side by side test ...\n");
    c = client->createSurface(
            String8("test-S3D_background"),
            0,
            DRAW_FHD_W,
            DRAW_FHD_H,
            PIXEL_FORMAT_RGBA_8888,
            ISurfaceComposer::eFXSurfaceDim & ISurfaceComposer::eFXSurfaceMask);

    u = client->createSurface(String8("test-S3D_image"), 0, sbs.width(), sbs.height(), PIXEL_FORMAT_RGBA_8888);
    //printf("tempc weakcount = %d\n", tempc->getWeakRefs()->getWeakCount());
    //c = tempc;
    //printf("after asign, tempc weakcount = %d, c weakcount = %d\n", tempc->getWeakRefs()->getWeakCount(),c->getWeakRefs()->getWeakCount());
    client->openGlobalTransaction();
    {
        c->setLayer(200000);
        c->setPosition(0, 0);
        c->setAlpha(1.0f);    // black background        
        u->setLayer(210000);
        u->setPosition(0, 0);
    }
	client->closeGlobalTransaction();

    printf("    set to SBS mode\n");
    client->openGlobalTransaction();
    {
        u->setFlags(ISurfaceComposer::eLayerSideBySide, ISurfaceComposer::eLayerS3DMask);
    }
	client->closeGlobalTransaction();

    s = u->getSurface();
    s->lock(&i);
    {
        memcpy(i.bits, sbs.getPixels(), sbs.width() * sbs.height() * sbs.bytesPerPixel());
    }
    s->unlockAndPost();

    sleep(1);

    client->dispose();
    return NO_ERROR;
}
示例#18
0
 static inline SkPMColor fetch(const SkBitmap& src, int x, int y) {
     return *src.getAddr32(x, y);
 }
示例#19
0
static void bitmap_to_pdf_pixels(const SkBitmap& bitmap, SkWStream* out) {
    if (!bitmap.getPixels()) {
        size_t size = pixel_count(bitmap) *
                      pdf_color_component_count(bitmap.colorType());
        fill_stream(out, '\x00', size);
        return;
    }
    SkBitmap copy;
    const SkBitmap& bm = not4444(bitmap, &copy);
    SkAutoLockPixels autoLockPixels(bm);
    switch (bm.colorType()) {
        case kN32_SkColorType: {
            SkASSERT(3 == pdf_color_component_count(bitmap.colorType()));
            SkAutoTMalloc<uint8_t> scanline(3 * bm.width());
            for (int y = 0; y < bm.height(); ++y) {
                const SkPMColor* src = bm.getAddr32(0, y);
                uint8_t* dst = scanline.get();
                for (int x = 0; x < bm.width(); ++x) {
                    SkPMColor color = *src++;
                    U8CPU alpha = SkGetPackedA32(color);
                    if (alpha != SK_AlphaTRANSPARENT) {
                        pmcolor_to_rgb24(color, dst);
                    } else {
                        get_neighbor_avg_color(bm, x, y, dst);
                    }
                    dst += 3;
                }
                out->write(scanline.get(), 3 * bm.width());
            }
            return;
        }
        case kRGB_565_SkColorType: {
            SkASSERT(3 == pdf_color_component_count(bitmap.colorType()));
            SkAutoTMalloc<uint8_t> scanline(3 * bm.width());
            for (int y = 0; y < bm.height(); ++y) {
                const uint16_t* src = bm.getAddr16(0, y);
                uint8_t* dst = scanline.get();
                for (int x = 0; x < bm.width(); ++x) {
                    U16CPU color565 = *src++;
                    *dst++ = SkPacked16ToR32(color565);
                    *dst++ = SkPacked16ToG32(color565);
                    *dst++ = SkPacked16ToB32(color565);
                }
                out->write(scanline.get(), 3 * bm.width());
            }
            return;
        }
        case kAlpha_8_SkColorType:
            SkASSERT(1 == pdf_color_component_count(bitmap.colorType()));
            fill_stream(out, '\x00', pixel_count(bm));
            return;
        case kGray_8_SkColorType:
        case kIndex_8_SkColorType:
            SkASSERT(1 == pdf_color_component_count(bitmap.colorType()));
            // these two formats need no transformation to serialize.
            for (int y = 0; y < bm.height(); ++y) {
                out->write(bm.getAddr8(0, y), bm.width());
            }
            return;
        case kUnknown_SkColorType:
        case kARGB_4444_SkColorType:
        default:
            SkDEBUGFAIL("unexpected color type");
    }
}
示例#20
0
 static inline SkPMColor fetch(const SkBitmap& src, int x, int y) {
     x = SkClampMax(x, src.width() - 1);
     y = SkClampMax(y, src.height() - 1);
     return *src.getAddr32(x, y);
 }
示例#21
0
/*  Fill out buffer with the compressed format Ganesh expects from a colortable
 based bitmap. [palette (colortable) + indices].

 At the moment Ganesh only supports 8bit version. If Ganesh allowed we others
 we could detect that the colortable.count is <= 16, and then repack the
 indices as nibbles to save RAM, but it would take more time (i.e. a lot
 slower than memcpy), so skipping that for now.

 Ganesh wants a full 256 palette entry, even though Skia's ctable is only as big
 as the colortable.count says it is.
 */
static void build_compressed_data(void* buffer, const SkBitmap& bitmap) {
    SkASSERT(SkBitmap::kIndex8_Config == bitmap.config());

    SkAutoLockPixels alp(bitmap);
    if (!bitmap.readyToDraw()) {
        SkDEBUGFAIL("bitmap not ready to draw!");
        return;
    }

    SkColorTable* ctable = bitmap.getColorTable();
    char* dst = (char*)buffer;

    uint32_t* colorTableDst = reinterpret_cast<uint32_t*>(dst);
    const uint32_t* colorTableSrc = reinterpret_cast<const uint32_t*>(ctable->lockColors());
    SkConvertConfig8888Pixels(colorTableDst, 0, SkCanvas::kRGBA_Premul_Config8888,
                              colorTableSrc, 0, SkCanvas::kNative_Premul_Config8888,
                              ctable->count(), 1);
    ctable->unlockColors();

    // always skip a full 256 number of entries, even if we memcpy'd fewer
    dst += kGrColorTableSize;

    if ((unsigned)bitmap.width() == bitmap.rowBytes()) {
        memcpy(dst, bitmap.getPixels(), bitmap.getSize());
    } else {
        // need to trim off the extra bytes per row
        size_t width = bitmap.width();
        size_t rowBytes = bitmap.rowBytes();
        const char* src = (const char*)bitmap.getPixels();
        for (int y = 0; y < bitmap.height(); y++) {
            memcpy(dst, src, width);
            src += rowBytes;
            dst += width;
        }
    }
}
示例#22
0
bool SkMagnifierImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src,
                                           const Context&, SkBitmap* dst,
                                           SkIPoint* offset) const {
    if ((src.colorType() != kN32_SkColorType) ||
        (fSrcRect.width() >= src.width()) ||
        (fSrcRect.height() >= src.height())) {
      return false;
    }

    SkAutoLockPixels alp(src);
    SkASSERT(src.getPixels());
    if (!src.getPixels() || src.width() <= 0 || src.height() <= 0) {
      return false;
    }

    SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(src.width(), src.height()));
    if (!device) {
        return false;
    }
    *dst = device->accessBitmap(false);
    SkAutoLockPixels alp_dst(*dst);

    SkScalar inv_inset = fInset > 0 ? SkScalarInvert(fInset) : SK_Scalar1;

    SkScalar inv_x_zoom = fSrcRect.width() / src.width();
    SkScalar inv_y_zoom = fSrcRect.height() / src.height();

    SkColor* sptr = src.getAddr32(0, 0);
    SkColor* dptr = dst->getAddr32(0, 0);
    int width = src.width(), height = src.height();
    for (int y = 0; y < height; ++y) {
        for (int x = 0; x < width; ++x) {
            SkScalar x_dist = SkMin32(x, width - x - 1) * inv_inset;
            SkScalar y_dist = SkMin32(y, height - y - 1) * inv_inset;
            SkScalar weight = 0;

            static const SkScalar kScalar2 = SkScalar(2);

            // To create a smooth curve at the corners, we need to work on
            // a square twice the size of the inset.
            if (x_dist < kScalar2 && y_dist < kScalar2) {
                x_dist = kScalar2 - x_dist;
                y_dist = kScalar2 - y_dist;

                SkScalar dist = SkScalarSqrt(SkScalarSquare(x_dist) +
                                             SkScalarSquare(y_dist));
                dist = SkMaxScalar(kScalar2 - dist, 0);
                weight = SkMinScalar(SkScalarSquare(dist), SK_Scalar1);
            } else {
                SkScalar sqDist = SkMinScalar(SkScalarSquare(x_dist),
                                              SkScalarSquare(y_dist));
                weight = SkMinScalar(sqDist, SK_Scalar1);
            }

            SkScalar x_interp = SkScalarMul(weight, (fSrcRect.x() + x * inv_x_zoom)) +
                           (SK_Scalar1 - weight) * x;
            SkScalar y_interp = SkScalarMul(weight, (fSrcRect.y() + y * inv_y_zoom)) +
                           (SK_Scalar1 - weight) * y;

            int x_val = SkTPin(SkScalarFloorToInt(x_interp), 0, width - 1);
            int y_val = SkTPin(SkScalarFloorToInt(y_interp), 0, height - 1);

            *dptr = sptr[y_val * width + x_val];
            dptr++;
        }
    }
    return true;
}
示例#23
0
static SkSize computeSize(const SkBitmap& bm, const SkMatrix& mat) {
    SkRect bounds = SkRect::MakeWH(SkIntToScalar(bm.width()),
                                   SkIntToScalar(bm.height()));
    mat.mapRect(&bounds);
    return SkSize::Make(bounds.width(), bounds.height());
}
static bool getBitmapInfo(const SkBitmap& bm,
                          size_t* bitsPerComponent,
                          CGBitmapInfo* info,
                          bool* upscaleTo32) {
    if (upscaleTo32) {
        *upscaleTo32 = false;
    }

    switch (bm.config()) {
        case SkBitmap::kRGB_565_Config:
            if (upscaleTo32) {
                *upscaleTo32 = true;
            }
            // fall through
        case SkBitmap::kARGB_8888_Config:
            *bitsPerComponent = 8;
#if SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
            *info = kCGBitmapByteOrder32Big;
            if (bm.isOpaque()) {
                *info |= kCGImageAlphaNoneSkipLast;
            } else {
                *info |= kCGImageAlphaPremultipliedLast;
            }
#elif SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
            // Matches the CGBitmapInfo that Apple recommends for best
            // performance, used by google chrome.
            *info = kCGBitmapByteOrder32Little;
            if (bm.isOpaque()) {
                *info |= kCGImageAlphaNoneSkipFirst;
            } else {
                *info |= kCGImageAlphaPremultipliedFirst;
            }
#else
            // ...add more formats as required...
#warning Cannot convert SkBitmap to CGImageRef with these shiftmasks. \
This will probably not work.
            // Legacy behavior. Perhaps turn this into an error at some
            // point.
            *info = kCGBitmapByteOrder32Big;
            if (bm.isOpaque()) {
                *info |= kCGImageAlphaNoneSkipLast;
            } else {
                *info |= kCGImageAlphaPremultipliedLast;
            }
#endif
            break;
#if 0
        case SkBitmap::kRGB_565_Config:
            // doesn't see quite right. Are they thinking 1555?
            *bitsPerComponent = 5;
            *info = kCGBitmapByteOrder16Little | kCGImageAlphaNone;
            break;
#endif
        case SkBitmap::kARGB_4444_Config:
            *bitsPerComponent = 4;
            *info = kCGBitmapByteOrder16Little;
            if (bm.isOpaque()) {
                *info |= kCGImageAlphaNoneSkipLast;
            } else {
                *info |= kCGImageAlphaPremultipliedLast;
            }
            break;
        default:
            return false;
    }
    return true;
}
示例#25
0
sk_sp<SkSpecialImage> SkMorphologyImageFilter::filterImageGeneric(bool dilate,
                                                                  SkSpecialImage* source,
                                                                  const Context& ctx,
                                                                  SkIPoint* offset) const {
    SkIPoint inputOffset = SkIPoint::Make(0, 0);
    sk_sp<SkSpecialImage> input(this->filterInput(0, source, ctx, &inputOffset));
    if (!input) {
        return nullptr;
    }

    SkIRect bounds;
    input = this->applyCropRect(this->mapContext(ctx), input.get(), &inputOffset, &bounds);
    if (!input) {
        return nullptr;
    }

    SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()),
                                     SkIntToScalar(this->radius().height()));
    ctx.ctm().mapVectors(&radius, 1);
    int width = SkScalarFloorToInt(radius.fX);
    int height = SkScalarFloorToInt(radius.fY);

    if (width < 0 || height < 0) {
        return nullptr;
    }

    SkIRect srcBounds = bounds;
    srcBounds.offset(-inputOffset);

    if (0 == width && 0 == height) {
        offset->fX = bounds.left();
        offset->fY = bounds.top();
        return input->makeSubset(srcBounds);
    }

#if SK_SUPPORT_GPU
    if (input->peekTexture() && input->peekTexture()->getContext()) {
        auto type = dilate ? GrMorphologyEffect::kDilate_MorphologyType
                           : GrMorphologyEffect::kErode_MorphologyType;
        sk_sp<SkSpecialImage> result(apply_morphology(input.get(), srcBounds, type,
                                                      SkISize::Make(width, height)));
        if (result) {
            offset->fX = bounds.left();
            offset->fY = bounds.top();
        }
        return result;
    }
#endif

    SkPixmap inputPixmap;

    if (!input->peekPixels(&inputPixmap)) {
        return nullptr;
    }

    if (inputPixmap.colorType() != kN32_SkColorType) {
        return nullptr;
    }

    SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(),
                                         inputPixmap.colorType(), inputPixmap.alphaType());

    SkBitmap dst;
    if (!dst.tryAllocPixels(info)) {
        return nullptr;
    }

    SkAutoLockPixels dstLock(dst);

    SkMorphologyImageFilter::Proc procX, procY;

    if (dilate) {
        procX = SkOpts::dilate_x;
        procY = SkOpts::dilate_y;
    } else {
        procX = SkOpts::erode_x;
        procY = SkOpts::erode_y;
    }

    if (width > 0 && height > 0) {
        SkBitmap tmp;
        if (!tmp.tryAllocPixels(info)) {
            return nullptr;
        }

        SkAutoLockPixels tmpLock(tmp);

        call_proc_X(procX, inputPixmap, &tmp, width, srcBounds);
        SkIRect tmpBounds = SkIRect::MakeWH(srcBounds.width(), srcBounds.height());
        call_proc_Y(procY,
                    tmp.getAddr32(tmpBounds.left(), tmpBounds.top()), tmp.rowBytesAsPixels(),
                    &dst, height, tmpBounds);
    } else if (width > 0) {
        call_proc_X(procX, inputPixmap, &dst, width, srcBounds);
    } else if (height > 0) {
        call_proc_Y(procY,
                    inputPixmap.addr32(srcBounds.left(), srcBounds.top()),
                    inputPixmap.rowBytesAsPixels(),
                    &dst, height, srcBounds);
    }
    offset->fX = bounds.left();
    offset->fY = bounds.top();

    return SkSpecialImage::MakeFromRaster(source->internal_getProxy(),
                                          SkIRect::MakeWH(bounds.width(), bounds.height()),
                                          dst);
}
示例#26
0
void Clipboard::WriteBitmap(const SkBitmap& bitmap)
{
    QImage image(reinterpret_cast<const uchar *>(bitmap.getPixels()), bitmap.width(), bitmap.height(), QImage::Format_ARGB32);
    getUncommittedData()->setImageData(image.copy());
}
示例#27
0
static void test_peekpixels(skiatest::Reporter* reporter) {
    const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);

    SkPixmap pmap;
    SkBitmap bm;

    // empty should return false
    REPORTER_ASSERT(reporter, !bm.peekPixels(nullptr));
    REPORTER_ASSERT(reporter, !bm.peekPixels(&pmap));

    // no pixels should return false
    bm.setInfo(SkImageInfo::MakeN32Premul(10, 10));
    REPORTER_ASSERT(reporter, !bm.peekPixels(nullptr));
    REPORTER_ASSERT(reporter, !bm.peekPixels(&pmap));

    // real pixels should return true
    bm.allocPixels(info);
    REPORTER_ASSERT(reporter, bm.peekPixels(nullptr));
    REPORTER_ASSERT(reporter, bm.peekPixels(&pmap));
    REPORTER_ASSERT(reporter, pmap.info() == bm.info());
    REPORTER_ASSERT(reporter, pmap.addr() == bm.getPixels());
    REPORTER_ASSERT(reporter, pmap.rowBytes() == bm.rowBytes());
    REPORTER_ASSERT(reporter, pmap.ctable() == bm.getColorTable());
}
示例#28
0
void SkScalerContext::getImage(const SkGlyph& origGlyph) {
    const SkGlyph*  glyph = &origGlyph;
    SkGlyph         tmpGlyph;

    if (fMaskFilter) {   // restore the prefilter bounds
        tmpGlyph.init(origGlyph.fID);

        // need the original bounds, sans our maskfilter
        SkMaskFilter* mf = fMaskFilter;
        fMaskFilter = NULL;             // temp disable
        this->getMetrics(&tmpGlyph);
        fMaskFilter = mf;               // restore

        tmpGlyph.fImage = origGlyph.fImage;

        // we need the prefilter bounds to be <= filter bounds
        SkASSERT(tmpGlyph.fWidth <= origGlyph.fWidth);
        SkASSERT(tmpGlyph.fHeight <= origGlyph.fHeight);
        glyph = &tmpGlyph;
    }

    if (fRec.fFrameWidth > 0 || fPathEffect != NULL || fRasterizer != NULL) {
        SkPath      devPath, fillPath;
        SkMatrix    fillToDevMatrix;

        this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix);

        const bool lcdMode = fRec.fMaskFormat == SkMask::kHorizontalLCD_Format ||
                             fRec.fMaskFormat == SkMask::kVerticalLCD_Format;

        if (fRasterizer) {
            SkMask  mask;

            glyph->toMask(&mask);
            mask.fFormat = SkMask::kA8_Format;
            sk_bzero(glyph->fImage, mask.computeImageSize());

            if (!fRasterizer->rasterize(fillPath, fillToDevMatrix, NULL,
                                        fMaskFilter, &mask,
                                        SkMask::kJustRenderImage_CreateMode)) {
                return;
            }
        } else {
            SkBitmap    bm;
            SkBitmap::Config config;
            SkMatrix    matrix;
            SkRegion    clip;
            SkPaint     paint;
            SkDraw      draw;

            if (SkMask::kA8_Format == fRec.fMaskFormat || lcdMode) {
                config = SkBitmap::kA8_Config;
                paint.setAntiAlias(true);
            } else {
                SkASSERT(SkMask::kBW_Format == fRec.fMaskFormat);
                config = SkBitmap::kA1_Config;
                paint.setAntiAlias(false);
            }

            clip.setRect(0, 0, glyph->fWidth, glyph->fHeight);
            matrix.setTranslate(-SkIntToScalar(glyph->fLeft),
                                -SkIntToScalar(glyph->fTop));
            bm.setConfig(config, glyph->fWidth, glyph->fHeight,
                         glyph->rowBytes());
            bm.setPixels(glyph->fImage);
            sk_bzero(glyph->fImage, bm.height() * bm.rowBytes());

            draw.fClip  = &clip;
            draw.fMatrix = &matrix;
            draw.fBitmap = &bm;
            draw.fBounder = NULL;
            draw.drawPath(devPath, paint);
        }

        if (lcdMode)
            glyph->expandA8ToLCD();
    } else {
        this->getGlyphContext(*glyph)->generateImage(*glyph);
    }

    if (fMaskFilter) {
        SkMask      srcM, dstM;
        SkMatrix    matrix;

        // the src glyph image shouldn't be 3D
        SkASSERT(SkMask::k3D_Format != glyph->fMaskFormat);
        glyph->toMask(&srcM);
        fRec.getMatrixFrom2x2(&matrix);

        if (fMaskFilter->filterMask(&dstM, srcM, matrix, NULL)) {
            int width = SkFastMin32(origGlyph.fWidth, dstM.fBounds.width());
            int height = SkFastMin32(origGlyph.fHeight, dstM.fBounds.height());
            int dstRB = origGlyph.rowBytes();
            int srcRB = dstM.fRowBytes;

            const uint8_t* src = (const uint8_t*)dstM.fImage;
            uint8_t* dst = (uint8_t*)origGlyph.fImage;

            if (SkMask::k3D_Format == dstM.fFormat) {
                // we have to copy 3 times as much
                height *= 3;
            }

            // clean out our glyph, since it may be larger than dstM
            //sk_bzero(dst, height * dstRB);

            while (--height >= 0) {
                memcpy(dst, src, width);
                src += srcRB;
                dst += dstRB;
            }
            SkMask::FreeImage(dstM.fImage);
        }
    }

    // check to see if we should filter the alpha channel

    if (NULL == fMaskFilter &&
        fRec.fMaskFormat != SkMask::kBW_Format &&
        fRec.fMaskFormat != SkMask::kLCD16_Format &&
        (fRec.fFlags & (kGammaForBlack_Flag | kGammaForWhite_Flag)) != 0)
    {
        const uint8_t* table = (fRec.fFlags & kGammaForBlack_Flag) ? gBlackGammaTable : gWhiteGammaTable;
        if (NULL != table)
        {
            uint8_t* dst = (uint8_t*)origGlyph.fImage;
            unsigned rowBytes = origGlyph.rowBytes();

            for (int y = origGlyph.fHeight - 1; y >= 0; --y)
            {
                for (int x = origGlyph.fWidth - 1; x >= 0; --x)
                    dst[x] = table[dst[x]];
                dst += rowBytes;
            }
        }
    }
}
void HwcDebug::dumpLayer(size_t layerIndex, hwc_layer_1_t hwLayers[])
{
    char dumpLogStrPng[128] = "";
    char dumpLogStrRaw[128] = "";
    bool needDumpPng = (mDumpCntrPng <= mDumpCntLimPng)? true:false;
    bool needDumpRaw = (mDumpCntrRaw <= mDumpCntLimRaw)? true:false;

    if (needDumpPng) {
        snprintf(dumpLogStrPng, sizeof(dumpLogStrPng),
            "[png-dump-frame: %03d of %03d]", mDumpCntrPng,
            mDumpCntLimPng);
    }
    if (needDumpRaw) {
        snprintf(dumpLogStrRaw, sizeof(dumpLogStrRaw),
            "[raw-dump-frame: %03d of %03d]", mDumpCntrRaw,
            mDumpCntLimRaw);
    }

    if (!(needDumpPng || needDumpRaw))
        return;

    if (NULL == hwLayers) {
        ALOGE("Display[%s] Layer[%zu] %s%s Error: No hwc layers to dump.",
            mDisplayName, layerIndex, dumpLogStrRaw, dumpLogStrPng);
        return;
    }

    hwc_layer_1_t *layer = &hwLayers[layerIndex];
    private_handle_t *hnd = (private_handle_t *)layer->handle;
    char pixFormatStr[32] = "None";

    if (NULL == hnd) {
        ALOGI("Display[%s] Layer[%zu] %s%s Skipping dump: Bufferless layer.",
            mDisplayName, layerIndex, dumpLogStrRaw, dumpLogStrPng);
        return;
    }

    getHalPixelFormatStr(hnd->format, pixFormatStr);
#ifdef QCOM_BSP
    if (needDumpPng && hnd->base) {
        bool bResult = false;
        char dumpFilename[PATH_MAX];
        SkBitmap *tempSkBmp = new SkBitmap();
        SkColorType tempSkBmpColor = kUnknown_SkColorType;
        snprintf(dumpFilename, sizeof(dumpFilename),
            "%s/sfdump%03d.layer%zu.%s.png", mDumpDirPng,
            mDumpCntrPng, layerIndex, mDisplayName);

        switch (hnd->format) {
            case HAL_PIXEL_FORMAT_RGBA_8888:
            case HAL_PIXEL_FORMAT_RGBX_8888:
                tempSkBmpColor = kRGBA_8888_SkColorType;
                break;
            case HAL_PIXEL_FORMAT_BGRA_8888:
                tempSkBmpColor = kBGRA_8888_SkColorType;
                break;
            case HAL_PIXEL_FORMAT_RGB_565:
                tempSkBmpColor = kRGB_565_SkColorType;
                break;
            case HAL_PIXEL_FORMAT_RGB_888:
            default:
                tempSkBmpColor = kUnknown_SkColorType;
                break;
        }
        if (kUnknown_SkColorType != tempSkBmpColor) {
            tempSkBmp->setInfo(SkImageInfo::Make(getWidth(hnd), getHeight(hnd),
                    tempSkBmpColor, kIgnore_SkAlphaType), 0);
            tempSkBmp->setPixels((void*)hnd->base);
            bResult = SkImageEncoder::EncodeFile(dumpFilename,
                                    *tempSkBmp, SkImageEncoder::kPNG_Type, 100);
            ALOGI("Display[%s] Layer[%zu] %s Dump to %s: %s",
                mDisplayName, layerIndex, dumpLogStrPng,
                dumpFilename, bResult ? "Success" : "Fail");
        } else {
            ALOGI("Display[%s] Layer[%zu] %s Skipping dump: Unsupported layer"
                " format %s for png encoder",
                mDisplayName, layerIndex, dumpLogStrPng, pixFormatStr);
        }
        delete tempSkBmp; // Calls SkBitmap::freePixels() internally.
    }
#endif
    if (needDumpRaw && hnd->base) {
        char dumpFilename[PATH_MAX];
        bool bResult = false;
        snprintf(dumpFilename, sizeof(dumpFilename),
            "%s/sfdump%03d.layer%zu.%dx%d.%s.%s.raw",
            mDumpDirRaw, mDumpCntrRaw,
            layerIndex, getWidth(hnd), getHeight(hnd),
            pixFormatStr, mDisplayName);
        FILE* fp = fopen(dumpFilename, "w+");
        if (NULL != fp) {
            bResult = (bool) fwrite((void*)hnd->base, hnd->size, 1, fp);
            fclose(fp);
        }
        ALOGI("Display[%s] Layer[%zu] %s Dump to %s: %s",
            mDisplayName, layerIndex, dumpLogStrRaw,
            dumpFilename, bResult ? "Success" : "Fail");
    }
}
示例#30
0
void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
                                    const SkRect* src, const SkRect& dst,
                                    const SkPaint& paint, SkCanvas::SrcRectConstraint constraint) {
    SkMatrix    matrix;
    SkRect      bitmapBounds, tmpSrc, tmpDst;
    SkBitmap    tmpBitmap;

    bitmapBounds.isetWH(bitmap.width(), bitmap.height());

    // Compute matrix from the two rectangles
    if (src) {
        tmpSrc = *src;
    } else {
        tmpSrc = bitmapBounds;
    }
    matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);

    LogDrawScaleFactor(SkMatrix::Concat(*draw.fMatrix, matrix), paint.getFilterQuality());

    const SkRect* dstPtr = &dst;
    const SkBitmap* bitmapPtr = &bitmap;

    // clip the tmpSrc to the bounds of the bitmap, and recompute dstRect if
    // needed (if the src was clipped). No check needed if src==null.
    if (src) {
        if (!bitmapBounds.contains(*src)) {
            if (!tmpSrc.intersect(bitmapBounds)) {
                return; // nothing to draw
            }
            // recompute dst, based on the smaller tmpSrc
            matrix.mapRect(&tmpDst, tmpSrc);
            dstPtr = &tmpDst;
        }
    }

    if (src && !src->contains(bitmapBounds) &&
        SkCanvas::kFast_SrcRectConstraint == constraint &&
        paint.getFilterQuality() != kNone_SkFilterQuality) {
        // src is smaller than the bounds of the bitmap, and we are filtering, so we don't know
        // how much more of the bitmap we need, so we can't use extractSubset or drawBitmap,
        // but we must use a shader w/ dst bounds (which can access all of the bitmap needed).
        goto USE_SHADER;
    }

    if (src) {
        // since we may need to clamp to the borders of the src rect within
        // the bitmap, we extract a subset.
        const SkIRect srcIR = tmpSrc.roundOut();
        if (!bitmap.extractSubset(&tmpBitmap, srcIR)) {
            return;
        }
        bitmapPtr = &tmpBitmap;

        // Since we did an extract, we need to adjust the matrix accordingly
        SkScalar dx = 0, dy = 0;
        if (srcIR.fLeft > 0) {
            dx = SkIntToScalar(srcIR.fLeft);
        }
        if (srcIR.fTop > 0) {
            dy = SkIntToScalar(srcIR.fTop);
        }
        if (dx || dy) {
            matrix.preTranslate(dx, dy);
        }

        SkRect extractedBitmapBounds;
        extractedBitmapBounds.isetWH(bitmapPtr->width(), bitmapPtr->height());
        if (extractedBitmapBounds == tmpSrc) {
            // no fractional part in src, we can just call drawBitmap
            goto USE_DRAWBITMAP;
        }
    } else {
        USE_DRAWBITMAP:
        // We can go faster by just calling drawBitmap, which will concat the
        // matrix with the CTM, and try to call drawSprite if it can. If not,
        // it will make a shader and call drawRect, as we do below.
        if (CanApplyDstMatrixAsCTM(matrix, paint)) {
            draw.drawBitmap(*bitmapPtr, matrix, dstPtr, paint);
            return;
        }
    }

    USE_SHADER:

    // Since the shader need only live for our stack-frame, pass in a custom allocator. This
    // can save malloc calls, and signals to SkMakeBitmapShader to not try to copy the bitmap
    // if its mutable, since that precaution is not needed (give the short lifetime of the shader).
    SkTBlitterAllocator allocator;
    // construct a shader, so we can call drawRect with the dst
    auto s = SkMakeBitmapShader(*bitmapPtr, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode,
                                &matrix, kNever_SkCopyPixelsMode, &allocator);
    if (!s) {
        return;
    }
    // we deliberately add a ref, since the allocator wants to be the last owner
    s.get()->ref();

    SkPaint paintWithShader(paint);
    paintWithShader.setStyle(SkPaint::kFill_Style);
    paintWithShader.setShader(s);

    // Call ourself, in case the subclass wanted to share this setup code
    // but handle the drawRect code themselves.
    this->drawRect(draw, *dstPtr, paintWithShader);
}