blob: 600c3361cb203427c98e77ca03e5d6e103eb2af4 [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
reed@google.comac10a2d2010-12-22 21:39:39 +0000115///////////////////////////////////////////////////////////////////////////////
116
bsalomon@google.comd302f142011-03-03 13:54:13 +0000117void SkGrClipIterator::reset(const SkClipStack& clipStack) {
118 fClipStack = &clipStack;
119 fIter.reset(clipStack);
120 // Gr has no notion of replace, skip to the
121 // last replace in the clip stack.
122 int lastReplace = 0;
123 int curr = 0;
124 while (NULL != (fCurr = fIter.next())) {
125 if (SkRegion::kReplace_Op == fCurr->fOp) {
126 lastReplace = curr;
127 }
128 ++curr;
129 }
130 fIter.reset(clipStack);
131 for (int i = 0; i < lastReplace+1; ++i) {
132 fCurr = fIter.next();
133 }
134}
135
136GrClipType SkGrClipIterator::getType() const {
137 GrAssert(!this->isDone());
scroggo7b118072011-03-23 15:04:26 +0000138 if (NULL == fCurr->fPath) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000139 return kRect_ClipType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000140 } else {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000141 return kPath_ClipType;
142 }
143}
144
145GrSetOp SkGrClipIterator::getOp() const {
146 // we skipped to the last "replace" op
147 // when this iter was reset.
148 // GrClip doesn't allow replace, so treat it as
149 // intersect.
150 GrSetOp skToGrOps[] = {
151 kDifference_SetOp, // kDifference_Op
152 kIntersect_SetOp, // kIntersect_Op
153 kUnion_SetOp, // kUnion_Op
154 kXor_SetOp, // kXOR_Op
155 kReverseDifference_SetOp, // kReverseDifference_Op
156 kIntersect_SetOp // kReplace_op
157 };
158 GR_STATIC_ASSERT(0 == SkRegion::kDifference_Op);
159 GR_STATIC_ASSERT(1 == SkRegion::kIntersect_Op);
160 GR_STATIC_ASSERT(2 == SkRegion::kUnion_Op);
161 GR_STATIC_ASSERT(3 == SkRegion::kXOR_Op);
162 GR_STATIC_ASSERT(4 == SkRegion::kReverseDifference_Op);
163 GR_STATIC_ASSERT(5 == SkRegion::kReplace_Op);
164 return skToGrOps[fCurr->fOp];
165}
166
167GrPathFill SkGrClipIterator::getPathFill() const {
168 switch (fCurr->fPath->getFillType()) {
169 case SkPath::kWinding_FillType:
170 return kWinding_PathFill;
171 case SkPath::kEvenOdd_FillType:
172 return kEvenOdd_PathFill;
173 case SkPath::kInverseWinding_FillType:
174 return kInverseWinding_PathFill;
175 case SkPath::kInverseEvenOdd_FillType:
176 return kInverseEvenOdd_PathFill;
177 default:
178 GrCrash("Unsupported path fill in clip.");
179 return kWinding_PathFill; // suppress warning
reed@google.comac10a2d2010-12-22 21:39:39 +0000180 }
181}
182
183///////////////////////////////////////////////////////////////////////////////
184
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000185GrPixelConfig SkGr::BitmapConfig2PixelConfig(SkBitmap::Config config,
reed@google.comac10a2d2010-12-22 21:39:39 +0000186 bool isOpaque) {
187 switch (config) {
188 case SkBitmap::kA8_Config:
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000189 return kAlpha_8_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000190 case SkBitmap::kIndex8_Config:
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000191 return kIndex_8_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000192 case SkBitmap::kRGB_565_Config:
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000193 return kRGB_565_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000194 case SkBitmap::kARGB_4444_Config:
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000195 return kRGBA_4444_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000196 case SkBitmap::kARGB_8888_Config:
197 if (isOpaque) {
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000198 return kRGBX_8888_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000199 } else {
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000200 return kRGBA_8888_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000201 }
202 default:
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000203 return kUnknown_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000204 }
205}
206