00001 /* 00002 * Copyright (C) 2008 The Android Open Source Project 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef SkFlipPixelRef_DEFINED 00018 #define SkFlipPixelRef_DEFINED 00019 00020 #include "SkBitmap.h" 00021 #include "SkPageFlipper.h" 00022 #include "SkPixelRef.h" 00023 #include "SkThread.h" 00024 00025 class SkRegion; 00026 00027 class SkFlipPixelRef : public SkPixelRef { 00028 public: 00029 SkFlipPixelRef(SkBitmap::Config, int width, int height); 00030 virtual ~SkFlipPixelRef(); 00031 00032 bool isDirty() const { return fFlipper.isDirty(); } 00033 const SkRegion& dirtyRgn() const { return fFlipper.dirtyRgn(); } 00034 00035 void inval() { fFlipper.inval(); } 00036 void inval(const SkIRect& rect) { fFlipper.inval(rect); } 00037 void inval(const SkRegion& rgn) { fFlipper.inval(rgn); } 00038 void inval(const SkRect& r, bool doAA) { fFlipper.inval(r, doAA); } 00039 00040 const SkRegion& beginUpdate(SkBitmap* device); 00041 void endUpdate(); 00042 00043 private: 00044 void getFrontBack(const void** front, void** back) const { 00045 if (front) { 00046 *front = fPage0; 00047 } 00048 if (back) { 00049 *back = fPage1; 00050 } 00051 } 00052 00053 void swapPages(); 00054 00055 // Helper to copy pixels from srcAddr to the dst bitmap, clipped to clip. 00056 // srcAddr points to memory with the same config as dst. 00057 static void CopyBitsFromAddr(const SkBitmap& dst, const SkRegion& clip, 00058 const void* srcAddr); 00059 00060 // serialization 00061 00062 public: 00063 virtual Factory getFactory() const { return Create; } 00064 virtual void flatten(SkFlattenableWriteBuffer&) const; 00065 static SkPixelRef* Create(SkFlattenableReadBuffer& buffer); 00066 00067 protected: 00068 virtual void* onLockPixels(SkColorTable**); 00069 virtual void onUnlockPixels(); 00070 00071 SkFlipPixelRef(SkFlattenableReadBuffer&); 00072 00073 private: 00074 SkMutex fMutex; 00075 SkPageFlipper fFlipper; 00076 00077 void* fStorage; 00078 void* fPage0; // points into fStorage; 00079 void* fPage1; // points into fStorage; 00080 size_t fSize; // size of 1 page. fStorage holds 2 pages 00081 SkBitmap::Config fConfig; 00082 00083 typedef SkPixelRef INHERITED; 00084 }; 00085 00086 class SkAutoFlipUpdate : SkNoncopyable { 00087 public: 00088 SkAutoFlipUpdate(SkFlipPixelRef* ref) : fRef(ref) { 00089 fDirty = &ref->beginUpdate(&fBitmap); 00090 } 00091 ~SkAutoFlipUpdate() { 00092 if (fRef) { 00093 fRef->endUpdate(); 00094 } 00095 } 00096 00097 const SkBitmap& bitmap() const { return fBitmap; } 00098 const SkRegion& dirty() const { return *fDirty; } 00099 00100 // optional. This gets automatically called in the destructor (only once) 00101 void endUpdate() { 00102 if (fRef) { 00103 fRef->endUpdate(); 00104 fRef = NULL; 00105 } 00106 } 00107 00108 private: 00109 SkFlipPixelRef* fRef; 00110 SkBitmap fBitmap; 00111 const SkRegion* fDirty; 00112 }; 00113 00114 #endif