blob: f65cf1ee148f4db8e2fabe28b1cde95badde8c87 [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
2 Copyright 2010 Google Inc.
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
18#include "SkGr.h"
19
20/* Fill out buffer with the compressed format Ganesh expects from a colortable
21 based bitmap. [palette (colortable) + indices].
bsalomon@google.com5782d712011-01-21 21:03:59 +000022
23 At the moment Ganesh only supports 8bit version. If Ganesh allowed we others
reed@google.comac10a2d2010-12-22 21:39:39 +000024 we could detect that the colortable.count is <= 16, and then repack the
25 indices as nibbles to save RAM, but it would take more time (i.e. a lot
26 slower than memcpy), so skipping that for now.
bsalomon@google.com5782d712011-01-21 21:03:59 +000027
reed@google.comac10a2d2010-12-22 21:39:39 +000028 Ganesh wants a full 256 palette entry, even though Skia's ctable is only as big
29 as the colortable.count says it is.
30 */
31static void build_compressed_data(void* buffer, const SkBitmap& bitmap) {
32 SkASSERT(SkBitmap::kIndex8_Config == bitmap.config());
bsalomon@google.com5782d712011-01-21 21:03:59 +000033
reed@google.comac10a2d2010-12-22 21:39:39 +000034 SkAutoLockPixels apl(bitmap);
35 if (!bitmap.readyToDraw()) {
36 SkASSERT(!"bitmap not ready to draw!");
37 return;
38 }
39
40 SkColorTable* ctable = bitmap.getColorTable();
41 char* dst = (char*)buffer;
bsalomon@google.com5782d712011-01-21 21:03:59 +000042
reed@google.comac10a2d2010-12-22 21:39:39 +000043 memcpy(dst, ctable->lockColors(), ctable->count() * sizeof(SkPMColor));
44 ctable->unlockColors(false);
bsalomon@google.com5782d712011-01-21 21:03:59 +000045
reed@google.comac10a2d2010-12-22 21:39:39 +000046 // always skip a full 256 number of entries, even if we memcpy'd fewer
bsalomon@google.comfea37b52011-04-25 15:51:06 +000047 dst += kGrColorTableSize;
reed@google.comac10a2d2010-12-22 21:39:39 +000048
49 if (bitmap.width() == bitmap.rowBytes()) {
50 memcpy(dst, bitmap.getPixels(), bitmap.getSize());
51 } else {
52 // need to trim off the extra bytes per row
53 size_t width = bitmap.width();
54 size_t rowBytes = bitmap.rowBytes();
55 const char* src = (const char*)bitmap.getPixels();
56 for (int y = 0; y < bitmap.height(); y++) {
57 memcpy(dst, src, width);
58 src += rowBytes;
59 dst += width;
60 }
61 }
62}
63
64////////////////////////////////////////////////////////////////////////////////
65
bsalomon@google.com5782d712011-01-21 21:03:59 +000066GrTextureEntry* sk_gr_create_bitmap_texture(GrContext* ctx,
reed@google.comac10a2d2010-12-22 21:39:39 +000067 GrTextureKey* key,
68 const GrSamplerState& sampler,
69 const SkBitmap& origBitmap) {
70 SkAutoLockPixels alp(origBitmap);
71 if (!origBitmap.readyToDraw()) {
72 return NULL;
73 }
74
75 SkBitmap tmpBitmap;
76
77 const SkBitmap* bitmap = &origBitmap;
bsalomon@google.com5782d712011-01-21 21:03:59 +000078
bsalomon@google.comfea37b52011-04-25 15:51:06 +000079 GrTextureDesc desc = {
80 kNone_GrTextureFlags,
81 kNone_GrAALevel,
reed@google.comac10a2d2010-12-22 21:39:39 +000082 bitmap->width(),
83 bitmap->height(),
84 SkGr::Bitmap2PixelConfig(*bitmap)
85 };
bsalomon@google.com5782d712011-01-21 21:03:59 +000086
reed@google.comac10a2d2010-12-22 21:39:39 +000087 if (SkBitmap::kIndex8_Config == bitmap->config()) {
88 // build_compressed_data doesn't do npot->pot expansion
89 // and paletted textures can't be sub-updated
90 if (ctx->supportsIndex8PixelConfig(sampler,
91 bitmap->width(), bitmap->height())) {
bsalomon@google.com5782d712011-01-21 21:03:59 +000092 size_t imagesize = bitmap->width() * bitmap->height() +
bsalomon@google.comfea37b52011-04-25 15:51:06 +000093 kGrColorTableSize;
reed@google.comac10a2d2010-12-22 21:39:39 +000094 SkAutoMalloc storage(imagesize);
bsalomon@google.com5782d712011-01-21 21:03:59 +000095
reed@google.comac10a2d2010-12-22 21:39:39 +000096 build_compressed_data(storage.get(), origBitmap);
97
98 // our compressed data will be trimmed, so pass width() for its
99 // "rowBytes", since they are the same now.
100 return ctx->createAndLockTexture(key, sampler, desc, storage.get(),
101 bitmap->width());
102
103 } else {
104 origBitmap.copyTo(&tmpBitmap, SkBitmap::kARGB_8888_Config);
105 // now bitmap points to our temp, which has been promoted to 32bits
106 bitmap = &tmpBitmap;
107 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000108 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000109
110 desc.fFormat = SkGr::Bitmap2PixelConfig(*bitmap);
111 return ctx->createAndLockTexture(key, sampler, desc, bitmap->getPixels(),
112 bitmap->rowBytes());
113}
114
115////////////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +0000116
reed@google.comac10a2d2010-12-22 21:39:39 +0000117
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000118GrPathCmd SkGrPathIter::next(GrPoint pts[]) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000119 GrAssert(NULL != pts);
120#if SK_SCALAR_IS_GR_SCALAR
121 return sk_path_verb_to_gr_path_command(fIter.next((SkPoint*)pts));
122#else
123 Command cmd = sk_path_verb_to_gr_path_command(fIter.next(fPoints));
124 int n = NumCommandPoints(cmd);
125 for (int i = 0; i < n; ++i) {
126 pts[i].fX = SkScalarToGrScalar(fPoints[i].fX);
127 pts[i].fY = SkScalarToGrScalar(fPoints[i].fY);
128 }
129 return cmd;
130#endif
131}
132
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000133GrPathCmd SkGrPathIter::next() {
reed@google.comac10a2d2010-12-22 21:39:39 +0000134 return sk_path_verb_to_gr_path_command(fIter.next(NULL));
135}
136
137void SkGrPathIter::rewind() {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000138 fIter.setPath(*fPath, false);
reed@google.comac10a2d2010-12-22 21:39:39 +0000139}
140
bsalomon@google.combf4338c2011-03-04 22:48:25 +0000141GrConvexHint SkGrPathIter::convexHint() const {
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000142 return fPath->isConvex() ? kConvex_ConvexHint :
143 kNone_ConvexHint;
reed@google.comac10a2d2010-12-22 21:39:39 +0000144}
145
bsalomon@google.com06e17952011-04-27 21:13:04 +0000146bool SkGrPathIter::getConservativeBounds(GrRect* rect) const {
reed@google.com20efde72011-05-09 17:00:02 +0000147 *rect = fPath->getBounds();
bsalomon@google.com06e17952011-04-27 21:13:04 +0000148 return true;
149}
150
reed@google.comac10a2d2010-12-22 21:39:39 +0000151///////////////////////////////////////////////////////////////////////////////
152
bsalomon@google.comd302f142011-03-03 13:54:13 +0000153void SkGrClipIterator::reset(const SkClipStack& clipStack) {
154 fClipStack = &clipStack;
155 fIter.reset(clipStack);
156 // Gr has no notion of replace, skip to the
157 // last replace in the clip stack.
158 int lastReplace = 0;
159 int curr = 0;
160 while (NULL != (fCurr = fIter.next())) {
161 if (SkRegion::kReplace_Op == fCurr->fOp) {
162 lastReplace = curr;
163 }
164 ++curr;
165 }
166 fIter.reset(clipStack);
167 for (int i = 0; i < lastReplace+1; ++i) {
168 fCurr = fIter.next();
169 }
170}
171
172GrClipType SkGrClipIterator::getType() const {
173 GrAssert(!this->isDone());
scroggo7b118072011-03-23 15:04:26 +0000174 if (NULL == fCurr->fPath) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000175 return kRect_ClipType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000176 } else {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000177 return kPath_ClipType;
178 }
179}
180
181GrSetOp SkGrClipIterator::getOp() const {
182 // we skipped to the last "replace" op
183 // when this iter was reset.
184 // GrClip doesn't allow replace, so treat it as
185 // intersect.
186 GrSetOp skToGrOps[] = {
187 kDifference_SetOp, // kDifference_Op
188 kIntersect_SetOp, // kIntersect_Op
189 kUnion_SetOp, // kUnion_Op
190 kXor_SetOp, // kXOR_Op
191 kReverseDifference_SetOp, // kReverseDifference_Op
192 kIntersect_SetOp // kReplace_op
193 };
194 GR_STATIC_ASSERT(0 == SkRegion::kDifference_Op);
195 GR_STATIC_ASSERT(1 == SkRegion::kIntersect_Op);
196 GR_STATIC_ASSERT(2 == SkRegion::kUnion_Op);
197 GR_STATIC_ASSERT(3 == SkRegion::kXOR_Op);
198 GR_STATIC_ASSERT(4 == SkRegion::kReverseDifference_Op);
199 GR_STATIC_ASSERT(5 == SkRegion::kReplace_Op);
200 return skToGrOps[fCurr->fOp];
201}
202
203GrPathFill SkGrClipIterator::getPathFill() const {
204 switch (fCurr->fPath->getFillType()) {
205 case SkPath::kWinding_FillType:
206 return kWinding_PathFill;
207 case SkPath::kEvenOdd_FillType:
208 return kEvenOdd_PathFill;
209 case SkPath::kInverseWinding_FillType:
210 return kInverseWinding_PathFill;
211 case SkPath::kInverseEvenOdd_FillType:
212 return kInverseEvenOdd_PathFill;
213 default:
214 GrCrash("Unsupported path fill in clip.");
215 return kWinding_PathFill; // suppress warning
reed@google.comac10a2d2010-12-22 21:39:39 +0000216 }
217}
218
219///////////////////////////////////////////////////////////////////////////////
220
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000221GrPixelConfig SkGr::BitmapConfig2PixelConfig(SkBitmap::Config config,
reed@google.comac10a2d2010-12-22 21:39:39 +0000222 bool isOpaque) {
223 switch (config) {
224 case SkBitmap::kA8_Config:
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000225 return kAlpha_8_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000226 case SkBitmap::kIndex8_Config:
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000227 return kIndex_8_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000228 case SkBitmap::kRGB_565_Config:
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000229 return kRGB_565_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000230 case SkBitmap::kARGB_4444_Config:
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000231 return kRGBA_4444_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000232 case SkBitmap::kARGB_8888_Config:
233 if (isOpaque) {
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000234 return kRGBX_8888_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000235 } else {
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000236 return kRGBA_8888_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000237 }
238 default:
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000239 return kUnknown_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000240 }
241}
242