diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-01-09 17:51:21 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-01-09 17:51:21 -0800 |
commit | 03202c9c3dfbf8c4feb0a1ee9b3680817e633f58 (patch) | |
tree | 1d0ba7cbf3e77c239527697ac455312b216c434e /include/images | |
parent | 37df15a82319228ae28fe5d99c010b288aad7091 (diff) | |
download | external_skia-03202c9c3dfbf8c4feb0a1ee9b3680817e633f58.zip external_skia-03202c9c3dfbf8c4feb0a1ee9b3680817e633f58.tar.gz external_skia-03202c9c3dfbf8c4feb0a1ee9b3680817e633f58.tar.bz2 |
auto import from //branches/cupcake/...@125939
Diffstat (limited to 'include/images')
-rw-r--r-- | include/images/SkFlipPixelRef.h | 114 | ||||
-rw-r--r-- | include/images/SkImageDecoder.h | 269 | ||||
-rw-r--r-- | include/images/SkImageEncoder.h | 36 | ||||
-rw-r--r-- | include/images/SkImageRef.h | 97 | ||||
-rw-r--r-- | include/images/SkImageRef_GlobalPool.h | 72 | ||||
-rw-r--r-- | include/images/SkMovie.h | 83 | ||||
-rw-r--r-- | include/images/SkPageFlipper.h | 70 |
7 files changed, 741 insertions, 0 deletions
diff --git a/include/images/SkFlipPixelRef.h b/include/images/SkFlipPixelRef.h new file mode 100644 index 0000000..3b4e97a --- /dev/null +++ b/include/images/SkFlipPixelRef.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SkFlipPixelRef_DEFINED +#define SkFlipPixelRef_DEFINED + +#include "SkBitmap.h" +#include "SkPageFlipper.h" +#include "SkPixelRef.h" +#include "SkThread.h" + +class SkRegion; + +class SkFlipPixelRef : public SkPixelRef { +public: + SkFlipPixelRef(SkBitmap::Config, int width, int height); + virtual ~SkFlipPixelRef(); + + bool isDirty() const { return fFlipper.isDirty(); } + const SkRegion& dirtyRgn() const { return fFlipper.dirtyRgn(); } + + void inval() { fFlipper.inval(); } + void inval(const SkIRect& rect) { fFlipper.inval(rect); } + void inval(const SkRegion& rgn) { fFlipper.inval(rgn); } + void inval(const SkRect& r, bool doAA) { fFlipper.inval(r, doAA); } + + const SkRegion& beginUpdate(SkBitmap* device); + void endUpdate(); + +private: + void getFrontBack(const void** front, void** back) const { + if (front) { + *front = fPage0; + } + if (back) { + *back = fPage1; + } + } + + void swapPages(); + + // Helper to copy pixels from srcAddr to the dst bitmap, clipped to clip. + // srcAddr points to memory with the same config as dst. + static void CopyBitsFromAddr(const SkBitmap& dst, const SkRegion& clip, + const void* srcAddr); + + // serialization + +public: + virtual Factory getFactory() const { return Create; } + virtual void flatten(SkFlattenableWriteBuffer&) const; + static SkPixelRef* Create(SkFlattenableReadBuffer& buffer); + +protected: + virtual void* onLockPixels(SkColorTable**); + virtual void onUnlockPixels(); + + SkFlipPixelRef(SkFlattenableReadBuffer&); + +private: + SkMutex fMutex; + SkPageFlipper fFlipper; + + void* fStorage; + void* fPage0; // points into fStorage; + void* fPage1; // points into fStorage; + size_t fSize; // size of 1 page. fStorage holds 2 pages + SkBitmap::Config fConfig; + + typedef SkPixelRef INHERITED; +}; + +class SkAutoFlipUpdate : SkNoncopyable { +public: + SkAutoFlipUpdate(SkFlipPixelRef* ref) : fRef(ref) { + fDirty = &ref->beginUpdate(&fBitmap); + } + ~SkAutoFlipUpdate() { + if (fRef) { + fRef->endUpdate(); + } + } + + const SkBitmap& bitmap() const { return fBitmap; } + const SkRegion& dirty() const { return *fDirty; } + + // optional. This gets automatically called in the destructor (only once) + void endUpdate() { + if (fRef) { + fRef->endUpdate(); + fRef = NULL; + } + } + +private: + SkFlipPixelRef* fRef; + SkBitmap fBitmap; + const SkRegion* fDirty; +}; + +#endif diff --git a/include/images/SkImageDecoder.h b/include/images/SkImageDecoder.h new file mode 100644 index 0000000..5b91c51 --- /dev/null +++ b/include/images/SkImageDecoder.h @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SkImageDecoder_DEFINED +#define SkImageDecoder_DEFINED + +#include "SkBitmap.h" +#include "SkRefCnt.h" + +class SkStream; + +/** \class SkImageDecoder + + Base class for decoding compressed images into a SkBitmap +*/ +class SkImageDecoder { +public: + virtual ~SkImageDecoder(); + + enum Format { + kUnknown_Format, + kBMP_Format, + kGIF_Format, + kICO_Format, + kJPEG_Format, + kPNG_Format, + kWBMP_Format, + + kLastKnownFormat = kWBMP_Format + }; + + /** Return the compressed data's format (see Format enum) + */ + virtual Format getFormat() const; + + /** Returns true if the decoder should try to dither the resulting image. + The default setting is true. + */ + bool getDitherImage() const { return fDitherImage; } + + /** Set to true if the the decoder should try to dither the resulting image. + The default setting is true. + */ + void setDitherImage(bool dither) { fDitherImage = dither; } + + /** \class Peeker + + Base class for optional callbacks to retrieve meta/chunk data out of + an image as it is being decoded. + */ + class Peeker : public SkRefCnt { + public: + /** Return true to continue decoding, or false to indicate an error, which + will cause the decoder to not return the image. + */ + virtual bool peek(const char tag[], const void* data, size_t length) = 0; + }; + + Peeker* getPeeker() const { return fPeeker; } + Peeker* setPeeker(Peeker*); + + /** \class Peeker + + Base class for optional callbacks to retrieve meta/chunk data out of + an image as it is being decoded. + */ + class Chooser : public SkRefCnt { + public: + virtual void begin(int count) {} + virtual void inspect(int index, SkBitmap::Config config, int width, int height) {} + /** Return the index of the subimage you want, or -1 to choose none of them. + */ + virtual int choose() = 0; + }; + + Chooser* getChooser() const { return fChooser; } + Chooser* setChooser(Chooser*); + + SkBitmap::Allocator* getAllocator() const { return fAllocator; } + SkBitmap::Allocator* setAllocator(SkBitmap::Allocator*); + + // sample-size, if set to > 1, tells the decoder to return a smaller than + // original bitmap, sampling 1 pixel for every size pixels. e.g. if sample + // size is set to 3, then the returned bitmap will be 1/3 as wide and high, + // and will contain 1/9 as many pixels as the original. + // Note: this is a hint, and the codec may choose to ignore this, or only + // approximate the sample size. + int getSampleSize() const { return fSampleSize; } + void setSampleSize(int size); + + /** Reset the sampleSize to its default of 1 + */ + void resetSampleSize() { this->setSampleSize(1); } + + /** Decoding is synchronous, but for long decodes, a different thread can + call this method safely. This sets a state that the decoders will + periodically check, and if they see it changed to cancel, they will + cancel. This will result in decode() returning false. However, there is + no guarantee that the decoder will see the state change in time, so + it is possible that cancelDecode() will be called, but will be ignored + and decode() will return true (assuming no other problems were + encountered). + + This state is automatically reset at the beginning of decode(). + */ + void cancelDecode() { + // now the subclass must query shouldCancelDecode() to be informed + // of the request + fShouldCancelDecode = true; + } + + /** Passed to the decode method. If kDecodeBounds_Mode is passed, then + only the bitmap's width/height/config need be set. If kDecodePixels_Mode + is passed, then the bitmap must have pixels or a pixelRef. + */ + enum Mode { + kDecodeBounds_Mode, //!< only return width/height/config in bitmap + kDecodePixels_Mode //!< return entire bitmap (including pixels) + }; + + /** Given a stream, decode it into the specified bitmap. + If the decoder can decompress the image, it calls bitmap.setConfig(), + and then if the Mode is kDecodePixels_Mode, call allocPixelRef(), + which will allocated a pixelRef. To access the pixel memory, the codec + needs to call lockPixels/unlockPixels on the + bitmap. It can then set the pixels with the decompressed image. + If the image cannot be decompressed, return false. + + note: document use of Allocator, Peeker and Chooser + */ + bool decode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref, Mode); + + /** Given a stream, this will try to find an appropriate decoder object. + If none is found, the method returns NULL. + */ + static SkImageDecoder* Factory(SkStream*); + + /** Decode the image stored in the specified file, and store the result + in bitmap. Return true for success or false on failure. + + If pref is kNo_Config, then the decoder is free to choose the most natural + config given the image data. If pref something other than kNo_Config, + the decoder will attempt to decode the image into that format, unless + there is a conflict (e.g. the image has per-pixel alpha and the bitmap's + config does not support that), in which case the decoder will choose a + closest match configuration. + */ + static bool DecodeFile(const char file[], SkBitmap* bitmap, + SkBitmap::Config prefConfig, Mode); + static bool DecodeFile(const char file[], SkBitmap* bitmap) + { + return DecodeFile(file, bitmap, SkBitmap::kNo_Config, kDecodePixels_Mode); + } + /** Decode the image stored in the specified memory buffer, and store the + result in bitmap. Return true for success or false on failure. + + If pref is kNo_Config, then the decoder is free to choose the most natural + config given the image data. If pref something other than kNo_Config, + the decoder will attempt to decode the image into that format, unless + there is a conflict (e.g. the image has per-pixel alpha and the bitmap's + config does not support that), in which case the decoder will choose a + closest match configuration. + */ + static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap, + SkBitmap::Config prefConfig, Mode); + static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap) + { + return DecodeMemory(buffer, size, bitmap, SkBitmap::kNo_Config, + kDecodePixels_Mode); + } + /** Decode the image stored in the specified SkStream, and store the result + in bitmap. Return true for success or false on failure. + + If pref is kNo_Config, then the decoder is free to choose the most + natural config given the image data. If pref something other than + kNo_Config, the decoder will attempt to decode the image into that + format, unless there is a conflict (e.g. the image has per-pixel alpha + and the bitmap's config does not support that), in which case the + decoder will choose a closest match configuration. + */ + static bool DecodeStream(SkStream* stream, SkBitmap* bitmap, + SkBitmap::Config prefConfig, Mode); + static bool DecodeStream(SkStream* stream, SkBitmap* bitmap) + { + return DecodeStream(stream, bitmap, SkBitmap::kNo_Config, + kDecodePixels_Mode); + } + + /* Given a format, return true if there is a currently installed decoder + for that format. Since a given build may not include all codecs (to save + code-size), this may return false. + */ + static bool SupportsFormat(Format); + + /** Return the default config for the running device. + Currently this used as a suggestion to image decoders that need to guess + what config they should decode into. + Default is kNo_Config, but this can be changed with SetDeviceConfig() + */ + static SkBitmap::Config GetDeviceConfig(); + /** Set the default config for the running device. + Currently this used as a suggestion to image decoders that need to guess + what config they should decode into. + Default is kNo_Config. + This can be queried with GetDeviceConfig() + */ + static void SetDeviceConfig(SkBitmap::Config); + + /** @cond UNIT_TEST */ + SkDEBUGCODE(static void UnitTest();) + /** @endcond */ + +protected: + // must be overridden in subclasses. This guy is called by decode(...) + virtual bool onDecode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref, + Mode) = 0; + + /** Can be queried from within onDecode, to see if the user (possibly in + a different thread) has requested the decode to cancel. If this returns + true, your onDecode() should stop and return false. + Each subclass needs to decide how often it can query this, to balance + responsiveness with performance. + + Calling this outside of onDecode() may return undefined values. + */ + +public: + bool shouldCancelDecode() const { return fShouldCancelDecode; } + +protected: + SkImageDecoder(); + + // helper function for decoders to handle the (common) case where there is only + // once choice available in the image file. + bool chooseFromOneChoice(SkBitmap::Config config, int width, int height) const; + + /* Helper for subclasses. Call this to allocate the pixel memory given the bitmap's + width/height/rowbytes/config. Returns true on success. This method handles checking + for an optional Allocator. + */ + bool allocPixelRef(SkBitmap*, SkColorTable*) const; + +private: + Peeker* fPeeker; + Chooser* fChooser; + SkBitmap::Allocator* fAllocator; + int fSampleSize; + bool fDitherImage; + mutable bool fShouldCancelDecode; + + // illegal + SkImageDecoder(const SkImageDecoder&); + SkImageDecoder& operator=(const SkImageDecoder&); +}; + +#endif diff --git a/include/images/SkImageEncoder.h b/include/images/SkImageEncoder.h new file mode 100644 index 0000000..94989c0 --- /dev/null +++ b/include/images/SkImageEncoder.h @@ -0,0 +1,36 @@ +#ifndef SkImageEncoder_DEFINED +#define SkImageEncoder_DEFINED + +#include "SkTypes.h" + +class SkBitmap; +class SkWStream; + +class SkImageEncoder { +public: + enum Type { + kJPEG_Type, + kPNG_Type + }; + static SkImageEncoder* Create(Type); + + virtual ~SkImageEncoder(); + + /* Quality ranges from 0..100 */ + enum { + kDefaultQuality = 80 + }; + + bool encodeFile(const char file[], const SkBitmap&, int quality); + bool encodeStream(SkWStream*, const SkBitmap&, int quality); + + static bool EncodeFile(const char file[], const SkBitmap&, Type, + int quality); + static bool EncodeStream(SkWStream*, const SkBitmap&, Type, + int quality); + +protected: + virtual bool onEncode(SkWStream*, const SkBitmap&, int quality) = 0; +}; + +#endif diff --git a/include/images/SkImageRef.h b/include/images/SkImageRef.h new file mode 100644 index 0000000..e94b7d4 --- /dev/null +++ b/include/images/SkImageRef.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SkImageRef_DEFINED +#define SkImageRef_DEFINED + +#include "SkPixelRef.h" +#include "SkBitmap.h" +#include "SkImageDecoder.h" +#include "SkString.h" + +class SkImageRefPool; +class SkStream; + +// define this to enable dumping whenever we add/remove/purge an imageref +//#define DUMP_IMAGEREF_LIFECYCLE + +class SkImageRef : public SkPixelRef { +public: + /** Create a new imageref from a stream. NOTE: the stream is not copied, but + since it may be accessed from another thread, the caller must ensure + that this imageref is the only owner of the stream. i.e. - sole + ownership of the stream object is transferred to this imageref object. + + @param stream The stream containing the encoded image data. Ownership + of this stream is transferred to the imageref, and + therefore the stream's ownercount must be 1. + @param config The preferred config of the decoded bitmap. + @param sampleSize Requested sampleSize for decoding. Defaults to 1. + */ + SkImageRef(SkStream*, SkBitmap::Config config, int sampleSize = 1); + virtual ~SkImageRef(); + + /** Return true if the image can be decoded. If so, and bitmap is non-null, + call its setConfig() with the corresponding values, but explicitly will + not set its pixels or colortable. Use SkPixelRef::lockPixels() for that. + + If there has been an error decoding the bitmap, this will return false + and ignore the bitmap parameter. + */ + bool getInfo(SkBitmap* bm); + + // overrides + virtual void flatten(SkFlattenableWriteBuffer&) const; + +protected: + /** Override if you want to install a custom allocator. + When this is called we will have already acquired the mutex! + */ + virtual bool onDecode(SkImageDecoder* codec, SkStream*, SkBitmap*, + SkBitmap::Config, SkImageDecoder::Mode); + + /* Overrides from SkPixelRef + When these are called, we will have already acquired the mutex! + */ + + virtual void* onLockPixels(SkColorTable**); + // override this in your subclass to clean up when we're unlocking pixels + virtual void onUnlockPixels(); + + SkImageRef(SkFlattenableReadBuffer&); + + SkBitmap fBitmap; + +private: + SkStream* setStream(SkStream*); + // called with mutex already held. returns true if the bitmap is in the + // requested state (or further, i.e. has pixels) + bool prepareBitmap(SkImageDecoder::Mode); + + SkStream* fStream; + SkBitmap::Config fConfig; + int fSampleSize; + bool fErrorInDecoding; + + friend class SkImageRefPool; + + SkImageRef* fPrev, *fNext; + size_t ramUsed() const; + + typedef SkPixelRef INHERITED; +}; + +#endif diff --git a/include/images/SkImageRef_GlobalPool.h b/include/images/SkImageRef_GlobalPool.h new file mode 100644 index 0000000..a9d4dce --- /dev/null +++ b/include/images/SkImageRef_GlobalPool.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SkImageRef_GlobalPool_DEFINED +#define SkImageRef_GlobalPool_DEFINED + +#include "SkImageRef.h" + +class SkImageRef_GlobalPool : public SkImageRef { +public: + // if pool is null, use the global pool + SkImageRef_GlobalPool(SkStream*, SkBitmap::Config, int sampleSize = 1); + virtual ~SkImageRef_GlobalPool(); + + // overrides + virtual Factory getFactory() const { + return Create; + } + static SkPixelRef* Create(SkFlattenableReadBuffer&); + + // API to control the global pool + + /** Return the amount specified as the budget for the cache (in bytes). + */ + static size_t GetRAMBudget(); + + /** Set a new budget value for the cache. + */ + static void SetRAMBudget(size_t); + + /** Return how much ram is currently in use by the global cache. + */ + static size_t GetRAMUsed(); + + /** Free up (approximately) enough such that the amount used by the cache + is <= the specified amount. Since some images may be "in use", the + amount actually freed may not always result in a ram usage value <= + to the requested amount. In addition, because of the + chunky nature of the cache, the resulting usage may be < the requested + amount. + */ + static void SetRAMUsed(size_t usageInBytes); + + static void DumpPool(); + +protected: + virtual bool onDecode(SkImageDecoder* codec, SkStream* stream, + SkBitmap* bitmap, SkBitmap::Config config, + SkImageDecoder::Mode mode); + + virtual void onUnlockPixels(); + + SkImageRef_GlobalPool(SkFlattenableReadBuffer&); + +private: + typedef SkImageRef INHERITED; +}; + +#endif diff --git a/include/images/SkMovie.h b/include/images/SkMovie.h new file mode 100644 index 0000000..45962a5 --- /dev/null +++ b/include/images/SkMovie.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SkMovie_DEFINED +#define SkMovie_DEFINED + +#include "SkRefCnt.h" +#include "SkCanvas.h" + +class SkStream; + +class SkMovie : public SkRefCnt { +public: + /** Try to create a movie from the stream. If the stream format is not + supported, return NULL. + */ + static SkMovie* DecodeStream(SkStream*); + /** Try to create a movie from the specified file path. If the file is not + found, or the format is not supported, return NULL. If a movie is + returned, the stream may be retained by the movie (via ref()) until + the movie is finished with it (by calling unref()). + */ + static SkMovie* DecodeFile(const char path[]); + /** Try to create a movie from the specified memory. + If the format is not supported, return NULL. If a movie is returned, + the data will have been read or copied, and so the caller may free + it. + */ + static SkMovie* DecodeMemory(const void* data, size_t length); + + SkMSec duration(); + int width(); + int height(); + int isOpaque(); + + /** Specify the time code (between 0...duration) to sample a bitmap + from the movie. Returns true if this time code generated a different + bitmap/frame from the previous state (i.e. true means you need to + redraw). + */ + bool setTime(SkMSec); + + // return the right bitmap for the current time code + const SkBitmap& bitmap(); + +protected: + struct Info { + SkMSec fDuration; + int fWidth; + int fHeight; + bool fIsOpaque; + }; + + virtual bool onGetInfo(Info*) = 0; + virtual bool onSetTime(SkMSec) = 0; + virtual bool onGetBitmap(SkBitmap*) = 0; + + // visible for subclasses + SkMovie(); + +private: + Info fInfo; + SkMSec fCurrTime; + SkBitmap fBitmap; + bool fNeedBitmap; + + void ensureInfo(); +}; + +#endif diff --git a/include/images/SkPageFlipper.h b/include/images/SkPageFlipper.h new file mode 100644 index 0000000..0d791ee --- /dev/null +++ b/include/images/SkPageFlipper.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SkPageFlipper_DEFINED +#define SkPageFlipper_DEFINED + +#include "SkRegion.h" + +/** SkPageFlipper manages alternating inval/dirty regions for a rectangular area + (like a bitmap). You call inval() to accumulate inval areas, and then when + you're ready to "flip" pages (i.e. draw into the one you've been + invalidating) you call update, which swaps the inval regions, and returns + two things to you: 1) the final inval region to be drawn into, and 2) the + region of pixels that should be copied from the "front" page onto the one + you're about to draw into. This copyBits region will be disjoint from the + inval region, so both need to be handled. + */ +class SkPageFlipper { +public: + SkPageFlipper(); + SkPageFlipper(int width, int height); + + int width() const { return fWidth; } + int height() const { return fHeight; } + + void resize(int width, int height); + + bool isDirty() const { return !fDirty1->isEmpty(); } + const SkRegion& dirtyRgn() const { return *fDirty1; } + + void inval(); + void inval(const SkIRect&); + void inval(const SkRegion&); + void inval(const SkRect&, bool antialias); + + /** When you're ready to write to the back page, call update. The returned + region is the invalidate are that needs to be drawn to. The copyBits + region (provided by the caller) is the area that should be copied from + the front page to the back page (will not intersect with the returned + inval region. + + Once this is called, the two internal regions are swapped, so the *new* + back inval region is ready to receive new inval calls. + */ + const SkRegion& update(SkRegion* copyBits); + +private: + SkRegion* fDirty0; + SkRegion* fDirty1; + SkRegion fDirty0Storage; + SkRegion fDirty1Storage; + int fWidth; + int fHeight; +}; + +#endif + |