michael@0: michael@0: /* michael@0: * Copyright 2008 The Android Open Source Project michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: michael@0: #ifndef SkPageFlipper_DEFINED michael@0: #define SkPageFlipper_DEFINED michael@0: michael@0: #include "SkRegion.h" michael@0: michael@0: /** SkPageFlipper manages alternating inval/dirty regions for a rectangular area michael@0: (like a bitmap). You call inval() to accumulate inval areas, and then when michael@0: you're ready to "flip" pages (i.e. draw into the one you've been michael@0: invalidating) you call update, which swaps the inval regions, and returns michael@0: two things to you: 1) the final inval region to be drawn into, and 2) the michael@0: region of pixels that should be copied from the "front" page onto the one michael@0: you're about to draw into. This copyBits region will be disjoint from the michael@0: inval region, so both need to be handled. michael@0: */ michael@0: class SkPageFlipper { michael@0: public: michael@0: SkPageFlipper(); michael@0: SkPageFlipper(int width, int height); michael@0: michael@0: int width() const { return fWidth; } michael@0: int height() const { return fHeight; } michael@0: michael@0: void resize(int width, int height); michael@0: michael@0: bool isDirty() const { return !fDirty1->isEmpty(); } michael@0: const SkRegion& dirtyRgn() const { return *fDirty1; } michael@0: michael@0: void inval(); michael@0: void inval(const SkIRect&); michael@0: void inval(const SkRegion&); michael@0: void inval(const SkRect&, bool antialias); michael@0: michael@0: /** When you're ready to write to the back page, call update. The returned michael@0: region is the invalidate are that needs to be drawn to. The copyBits michael@0: region (provided by the caller) is the area that should be copied from michael@0: the front page to the back page (will not intersect with the returned michael@0: inval region. michael@0: michael@0: Once this is called, the two internal regions are swapped, so the *new* michael@0: back inval region is ready to receive new inval calls. michael@0: */ michael@0: const SkRegion& update(SkRegion* copyBits); michael@0: michael@0: private: michael@0: SkRegion* fDirty0; michael@0: SkRegion* fDirty1; michael@0: SkRegion fDirty0Storage; michael@0: SkRegion fDirty1Storage; michael@0: int fWidth; michael@0: int fHeight; michael@0: }; michael@0: michael@0: #endif