bool SkWindow::update(SkIRect* updateArea) { if (!fDirtyRgn.isEmpty()) { SkBitmap bm = this->getBitmap(); #if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN) char* buffer = (char*)GXBeginDraw(); SkASSERT(buffer); RECT rect; GetWindowRect((HWND)((SkOSWindow*)this)->getHWND(), &rect); buffer += rect.top * gDisplayProps.cbyPitch + rect.left * gDisplayProps.cbxPitch; bm.setPixels(buffer); #endif SkAutoTUnref<SkSurface> surface(this->createSurface()); SkCanvas* canvas = surface->getCanvas(); canvas->clipRegion(fDirtyRgn); if (updateArea) *updateArea = fDirtyRgn.getBounds(); SkAutoCanvasRestore acr(canvas, true); canvas->concat(fMatrix); // empty this now, so we can correctly record any inval calls that // might be made during the draw call. fDirtyRgn.setEmpty(); #ifdef SK_SIMULATE_FAILED_MALLOC gEnableControlledThrow = true; #endif #ifdef SK_BUILD_FOR_WIN32 //try { this->draw(canvas); //} //catch (...) { //} #else this->draw(canvas); #endif #ifdef SK_SIMULATE_FAILED_MALLOC gEnableControlledThrow = false; #endif #if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN) GXEndDraw(); #endif return true; } return false; }
SkCanvas* TiledPictureRenderer::setupCanvas(int width, int height) { SkCanvas* canvas = this->INHERITED::setupCanvas(width, height); SkASSERT(fPicture); // Clip the tile to an area that is completely inside both the SkPicture and the viewport. This // is mostly important for tiles on the right and bottom edges as they may go over this area and // the picture may have some commands that draw outside of this area and so should not actually // be written. // Uses a clipRegion so that it will be unaffected by the scale factor, which may have been set // by INHERITED::setupCanvas. SkRegion clipRegion; clipRegion.setRect(0, 0, this->getViewWidth(), this->getViewHeight()); canvas->clipRegion(clipRegion); return canvas; }
bool SkWindow::update(SkIRect* updateArea) { if (!fDirtyRgn.isEmpty()) { SkAutoTUnref<SkSurface> surface(this->createSurface()); SkCanvas* canvas = surface->getCanvas(); canvas->clipRegion(fDirtyRgn); if (updateArea) { *updateArea = fDirtyRgn.getBounds(); } SkAutoCanvasRestore acr(canvas, true); canvas->concat(fMatrix); // empty this now, so we can correctly record any inval calls that // might be made during the draw call. fDirtyRgn.setEmpty(); #ifdef SK_SIMULATE_FAILED_MALLOC gEnableControlledThrow = true; #endif #ifdef SK_BUILD_FOR_WIN32 //try { this->draw(canvas); //} //catch (...) { //} #else this->draw(canvas); #endif #ifdef SK_SIMULATE_FAILED_MALLOC gEnableControlledThrow = false; #endif return true; } return false; }
static void test_complex_clips(skiatest::Reporter* reporter) { #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG const int WIDTH = 400; const int HEIGHT = 400; const int SPACER = 10; SkIRect layerRect = SkIRect::MakeWH(WIDTH, HEIGHT / 4); layerRect.inset(2*SPACER, 2*SPACER); SkIRect clipRect = layerRect; clipRect.fRight = clipRect.fLeft + (clipRect.width() / 2) - (2*SPACER); clipRect.outset(SPACER, SPACER); SkIRect regionBounds = clipRect; regionBounds.offset(clipRect.width() + (2*SPACER), 0); SkIRect regionInterior = regionBounds; regionInterior.inset(SPACER*3, SPACER*3); SkRegion clipRegion; clipRegion.setRect(regionBounds); clipRegion.op(regionInterior, SkRegion::kDifference_Op); const SkRegion::Op clipOps[] = { SkRegion::kIntersect_Op, SkRegion::kIntersect_Op, SkRegion::kReplace_Op, }; const SkCanvas::SaveFlags flags[] = { SkCanvas::kARGB_NoClipLayer_SaveFlag, SkCanvas::kARGB_ClipLayer_SaveFlag, SkCanvas::kARGB_NoClipLayer_SaveFlag, }; REPORTER_ASSERT(reporter, sizeof(clipOps) == sizeof(flags)); const int layerCombinations = sizeof(flags) / sizeof(SkCanvas::SaveFlags); SkBitmap bitmaps[2]; for (int i = 0; i < 2; ++i) { bitmaps[i].allocN32Pixels(WIDTH, HEIGHT); SkCanvas canvas(bitmaps[i]); canvas.drawColor(SK_ColorRED); SkRegion localRegion = clipRegion; for (int j = 0; j < layerCombinations; ++j) { SkRect layerBounds = SkRect::Make(layerRect); canvas.saveLayerAlpha(&layerBounds, 128, flags[j]); SkCanvasState* state = NULL; SkCanvas* tmpCanvas = NULL; if (i) { state = SkCanvasStateUtils::CaptureCanvasState(&canvas); REPORTER_ASSERT(reporter, state); tmpCanvas = SkCanvasStateUtils::CreateFromCanvasState(state); REPORTER_ASSERT(reporter, tmpCanvas); } else { tmpCanvas = SkRef(&canvas); } tmpCanvas->save(); tmpCanvas->clipRect(SkRect::Make(clipRect), clipOps[j]); tmpCanvas->drawColor(SK_ColorBLUE); tmpCanvas->restore(); tmpCanvas->clipRegion(localRegion, clipOps[j]); tmpCanvas->drawColor(SK_ColorBLUE); tmpCanvas->unref(); SkCanvasStateUtils::ReleaseCanvasState(state); canvas.restore(); // translate the canvas and region for the next iteration canvas.translate(0, SkIntToScalar(2*(layerRect.height() + (SPACER)))); localRegion.translate(0, 2*(layerRect.height() + SPACER)); } } // now we memcmp the two bitmaps REPORTER_ASSERT(reporter, bitmaps[0].getSize() == bitmaps[1].getSize()); REPORTER_ASSERT(reporter, !memcmp(bitmaps[0].getPixels(), bitmaps[1].getPixels(), bitmaps[0].getSize())); #endif }
static jobject Surface_lockCanvas(JNIEnv* env, jobject clazz, jobject dirtyRect) { const sp<Surface>& surface(getSurface(env, clazz)); if (!Surface::isValid(surface)) { doThrowIAE(env); return 0; } // get dirty region Region dirtyRegion; if (dirtyRect) { Rect dirty; dirty.left = env->GetIntField(dirtyRect, ro.l); dirty.top = env->GetIntField(dirtyRect, ro.t); dirty.right = env->GetIntField(dirtyRect, ro.r); dirty.bottom= env->GetIntField(dirtyRect, ro.b); if (!dirty.isEmpty()) { dirtyRegion.set(dirty); } } else { dirtyRegion.set(Rect(0x3FFF,0x3FFF)); } Surface::SurfaceInfo info; status_t err = surface->lock(&info, &dirtyRegion); if (err < 0) { const char* const exception = (err == NO_MEMORY) ? OutOfResourcesException : "java/lang/IllegalArgumentException"; jniThrowException(env, exception, NULL); return 0; } // Associate a SkCanvas object to this surface jobject canvas = env->GetObjectField(clazz, so.canvas); env->SetIntField(canvas, co.surfaceFormat, info.format); SkCanvas* nativeCanvas = (SkCanvas*)env->GetIntField(canvas, no.native_canvas); SkBitmap bitmap; ssize_t bpr = info.s * bytesPerPixel(info.format); bitmap.setConfig(convertPixelFormat(info.format), info.w, info.h, bpr); if (info.format == PIXEL_FORMAT_RGBX_8888) { bitmap.setIsOpaque(true); } if (info.w > 0 && info.h > 0) { bitmap.setPixels(info.bits); } else { // be safe with an empty bitmap. bitmap.setPixels(NULL); } nativeCanvas->setBitmapDevice(bitmap); SkRegion clipReg; if (dirtyRegion.isRect()) { // very common case const Rect b(dirtyRegion.getBounds()); clipReg.setRect(b.left, b.top, b.right, b.bottom); } else { size_t count; Rect const* r = dirtyRegion.getArray(&count); while (count) { clipReg.op(r->left, r->top, r->right, r->bottom, SkRegion::kUnion_Op); r++, count--; } } nativeCanvas->clipRegion(clipReg); int saveCount = nativeCanvas->save(); env->SetIntField(clazz, so.saveCount, saveCount); if (dirtyRect) { const Rect& bounds(dirtyRegion.getBounds()); env->SetIntField(dirtyRect, ro.l, bounds.left); env->SetIntField(dirtyRect, ro.t, bounds.top); env->SetIntField(dirtyRect, ro.r, bounds.right); env->SetIntField(dirtyRect, ro.b, bounds.bottom); } return canvas; }