1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SkFlipPixelRef_DEFINED
18#define SkFlipPixelRef_DEFINED
19
20#include "SkBitmap.h"
21#include "SkPageFlipper.h"
22#include "SkPixelRef.h"
23#include "SkThread.h"
24
25class SkRegion;
26
27class SkFlipPixelRef : public SkPixelRef {
28public:
29            SkFlipPixelRef(SkBitmap::Config, int width, int height);
30    virtual ~SkFlipPixelRef();
31
32    bool isDirty() const { return fFlipper.isDirty(); }
33    const SkRegion& dirtyRgn() const { return fFlipper.dirtyRgn(); }
34
35    void inval() { fFlipper.inval(); }
36    void inval(const SkIRect& rect) { fFlipper.inval(rect); }
37    void inval(const SkRegion& rgn) { fFlipper.inval(rgn); }
38    void inval(const SkRect& r, bool doAA) { fFlipper.inval(r, doAA); }
39
40    const SkRegion& beginUpdate(SkBitmap* device);
41    void endUpdate();
42
43private:
44    void getFrontBack(const void** front, void** back) const {
45        if (front) {
46            *front = fPage0;
47        }
48        if (back) {
49            *back = fPage1;
50        }
51    }
52
53    void    swapPages();
54
55    // Helper to copy pixels from srcAddr to the dst bitmap, clipped to clip.
56    // srcAddr points to memory with the same config as dst.
57    static void CopyBitsFromAddr(const SkBitmap& dst, const SkRegion& clip,
58                                 const void* srcAddr);
59
60    // serialization
61
62public:
63    virtual Factory getFactory() const { return Create; }
64    virtual void flatten(SkFlattenableWriteBuffer&) const;
65    static SkPixelRef* Create(SkFlattenableReadBuffer& buffer);
66
67protected:
68    virtual void* onLockPixels(SkColorTable**);
69    virtual void onUnlockPixels();
70
71    SkFlipPixelRef(SkFlattenableReadBuffer&);
72
73private:
74    SkMutex         fMutex;
75    SkPageFlipper   fFlipper;
76
77    void*           fStorage;
78    void*           fPage0; // points into fStorage;
79    void*           fPage1; // points into fStorage;
80    size_t          fSize;  // size of 1 page. fStorage holds 2 pages
81    SkBitmap::Config fConfig;
82
83    typedef SkPixelRef INHERITED;
84};
85
86class SkAutoFlipUpdate : SkNoncopyable {
87public:
88    SkAutoFlipUpdate(SkFlipPixelRef* ref) : fRef(ref) {
89        fDirty = &ref->beginUpdate(&fBitmap);
90    }
91    ~SkAutoFlipUpdate() {
92        if (fRef) {
93            fRef->endUpdate();
94        }
95    }
96
97    const SkBitmap& bitmap() const { return fBitmap; }
98    const SkRegion& dirty() const { return *fDirty; }
99
100    // optional. This gets automatically called in the destructor (only once)
101    void endUpdate() {
102        if (fRef) {
103            fRef->endUpdate();
104            fRef = NULL;
105        }
106    }
107
108private:
109    SkFlipPixelRef* fRef;
110    SkBitmap        fBitmap;
111    const SkRegion* fDirty;
112};
113
114#endif
115