OLD | NEW |
| (Empty) |
1 #include "SkFlipPixelRef.h" | |
2 #include "SkFlattenable.h" | |
3 #include "SkRegion.h" | |
4 | |
5 SkFlipPixelRef::SkFlipPixelRef(SkBitmap::Config config, int width, int height) | |
6 : fFlipper(width, height) { | |
7 fConfig = config; | |
8 fSize = SkBitmap::ComputeSize(config, width, height); | |
9 fStorage = sk_malloc_throw(fSize << 1); | |
10 fPage0 = fStorage; | |
11 fPage1 = (char*)fStorage + fSize; | |
12 } | |
13 | |
14 SkFlipPixelRef::~SkFlipPixelRef() { | |
15 sk_free(fStorage); | |
16 } | |
17 | |
18 const SkRegion& SkFlipPixelRef::beginUpdate(SkBitmap* device) { | |
19 void* writeAddr; | |
20 const void* readAddr; | |
21 this->getFrontBack(&readAddr, &writeAddr); | |
22 | |
23 device->setConfig(fConfig, fFlipper.width(), fFlipper.height()); | |
24 device->setPixels(writeAddr); | |
25 | |
26 SkRegion copyBits; | |
27 const SkRegion& dirty = fFlipper.update(©Bits); | |
28 | |
29 SkFlipPixelRef::CopyBitsFromAddr(*device, copyBits, readAddr); | |
30 return dirty; | |
31 } | |
32 | |
33 void SkFlipPixelRef::endUpdate() { | |
34 this->swapPages(); | |
35 } | |
36 | |
37 /////////////////////////////////////////////////////////////////////////////// | |
38 | |
39 void* SkFlipPixelRef::onLockPixels(SkColorTable** ct) { | |
40 fMutex.acquire(); | |
41 *ct = NULL; | |
42 return fPage0; | |
43 } | |
44 | |
45 void SkFlipPixelRef::onUnlockPixels() { | |
46 fMutex.release(); | |
47 } | |
48 | |
49 void SkFlipPixelRef::swapPages() { | |
50 fMutex.acquire(); | |
51 SkTSwap<void*>(fPage0, fPage1); | |
52 fMutex.release(); | |
53 } | |
54 | |
55 void SkFlipPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const { | |
56 this->INHERITED::flatten(buffer); | |
57 | |
58 buffer.write32(fSize); | |
59 // only need to write page0 | |
60 buffer.writePad(fPage0, fSize); | |
61 } | |
62 | |
63 SkFlipPixelRef::SkFlipPixelRef(SkFlattenableReadBuffer& buffer) | |
64 : INHERITED(buffer, NULL) { | |
65 fSize = buffer.readU32(); | |
66 fStorage = sk_malloc_throw(fSize << 1); | |
67 fPage0 = fStorage; | |
68 fPage1 = (char*)fStorage + fSize; | |
69 buffer.read(fPage0, fSize); | |
70 } | |
71 | |
72 SkPixelRef* SkFlipPixelRef::Create(SkFlattenableReadBuffer& buffer) { | |
73 return SkNEW_ARGS(SkFlipPixelRef, (buffer)); | |
74 } | |
75 | |
76 static SkPixelRef::Registrar::Registrar reg("SkFlipPixelRef", | |
77 SkFlipPixelRef::Create); | |
78 | |
79 /////////////////////////////////////////////////////////////////////////////// | |
80 | |
81 static void copyRect(const SkBitmap& dst, const SkIRect& rect, | |
82 const void* srcAddr, int shift) { | |
83 const size_t offset = rect.fTop * dst.rowBytes() + (rect.fLeft << shift); | |
84 char* dstP = static_cast<char*>(dst.getPixels()) + offset; | |
85 const char* srcP = static_cast<const char*>(srcAddr) + offset; | |
86 const size_t rb = dst.rowBytes(); | |
87 const size_t bytes = rect.width() << shift; | |
88 | |
89 int height = rect.height(); | |
90 while (--height >= 0) { | |
91 memcpy(dstP, srcP, bytes); | |
92 dstP += rb; | |
93 srcP += rb; | |
94 } | |
95 } | |
96 | |
97 static int getShift(SkBitmap::Config config) { | |
98 switch (config) { | |
99 case SkBitmap::kARGB_8888_Config: | |
100 return 2; | |
101 case SkBitmap::kRGB_565_Config: | |
102 case SkBitmap::kARGB_4444_Config: | |
103 return 1; | |
104 case SkBitmap::kIndex8_Config: | |
105 case SkBitmap::kA8_Config: | |
106 return 0; | |
107 default: | |
108 return -1; // signal not supported | |
109 } | |
110 } | |
111 | |
112 void SkFlipPixelRef::CopyBitsFromAddr(const SkBitmap& dst, const SkRegion& clip, | |
113 const void* srcAddr) { | |
114 const int shift = getShift(dst.config()); | |
115 if (shift < 0) { | |
116 return; | |
117 } | |
118 | |
119 const SkIRect bounds = {0, 0, dst.width(), dst.height()}; | |
120 SkRegion::Cliperator iter(clip, bounds); | |
121 | |
122 while (!iter.done()) { | |
123 copyRect(dst, iter.rect(), srcAddr, shift); | |
124 iter.next(); | |
125 } | |
126 } | |
127 | |
OLD | NEW |