blob: 49b17e74baac9e56dce2390a5b6371871775f27e [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.com50398bf2011-07-26 20:45:30 +000066GrContext::TextureCacheEntry sk_gr_create_bitmap_texture(GrContext* ctx,
67 GrContext::TextureKey key,
68 const GrSamplerState& sampler,
69 const SkBitmap& origBitmap) {
reed@google.comac10a2d2010-12-22 21:39:39 +000070 SkAutoLockPixels alp(origBitmap);
bsalomon@google.com50398bf2011-07-26 20:45:30 +000071 GrContext::TextureCacheEntry entry;
72
reed@google.comac10a2d2010-12-22 21:39:39 +000073 if (!origBitmap.readyToDraw()) {
bsalomon@google.com50398bf2011-07-26 20:45:30 +000074 return entry;
reed@google.comac10a2d2010-12-22 21:39:39 +000075 }
76
77 SkBitmap tmpBitmap;
78
79 const SkBitmap* bitmap = &origBitmap;
bsalomon@google.com5782d712011-01-21 21:03:59 +000080
bsalomon@google.comfea37b52011-04-25 15:51:06 +000081 GrTextureDesc desc = {
82 kNone_GrTextureFlags,
83 kNone_GrAALevel,
reed@google.comac10a2d2010-12-22 21:39:39 +000084 bitmap->width(),
85 bitmap->height(),
86 SkGr::Bitmap2PixelConfig(*bitmap)
87 };
bsalomon@google.com5782d712011-01-21 21:03:59 +000088
reed@google.comac10a2d2010-12-22 21:39:39 +000089 if (SkBitmap::kIndex8_Config == bitmap->config()) {
90 // build_compressed_data doesn't do npot->pot expansion
91 // and paletted textures can't be sub-updated
92 if (ctx->supportsIndex8PixelConfig(sampler,
93 bitmap->width(), bitmap->height())) {
bsalomon@google.com5782d712011-01-21 21:03:59 +000094 size_t imagesize = bitmap->width() * bitmap->height() +
bsalomon@google.comfea37b52011-04-25 15:51:06 +000095 kGrColorTableSize;
reed@google.comac10a2d2010-12-22 21:39:39 +000096 SkAutoMalloc storage(imagesize);
bsalomon@google.com5782d712011-01-21 21:03:59 +000097
reed@google.comac10a2d2010-12-22 21:39:39 +000098 build_compressed_data(storage.get(), origBitmap);
99
100 // our compressed data will be trimmed, so pass width() for its
101 // "rowBytes", since they are the same now.
junov@google.com4ee7ae52011-06-30 17:30:49 +0000102
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000103 if (gUNCACHED_KEY != key) {
junov@google.com4ee7ae52011-06-30 17:30:49 +0000104 return ctx->createAndLockTexture(key, sampler, desc, storage.get(),
105 bitmap->width());
106 } else {
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000107 entry = ctx->lockScratchTexture(desc,
108 GrContext::kExact_ScratchTexMatch);
109 entry.texture()->uploadTextureData(0, 0, bitmap->width(),
junov@google.com4ee7ae52011-06-30 17:30:49 +0000110 bitmap->height(), storage.get(), 0);
111 return entry;
112 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000113
114 } else {
115 origBitmap.copyTo(&tmpBitmap, SkBitmap::kARGB_8888_Config);
116 // now bitmap points to our temp, which has been promoted to 32bits
117 bitmap = &tmpBitmap;
118 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000119 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000120
121 desc.fFormat = SkGr::Bitmap2PixelConfig(*bitmap);
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000122 if (gUNCACHED_KEY != key) {
123 return ctx->createAndLockTexture(key, sampler, desc,
124 bitmap->getPixels(),
125 bitmap->rowBytes());
junov@google.com4ee7ae52011-06-30 17:30:49 +0000126 } else {
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000127 entry = ctx->lockScratchTexture(desc,
128 GrContext::kExact_ScratchTexMatch);
129 entry.texture()->uploadTextureData(0, 0, bitmap->width(),
junov@google.com4ee7ae52011-06-30 17:30:49 +0000130 bitmap->height(), bitmap->getPixels(), bitmap->rowBytes());
131 return entry;
132 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000133}
134
reed@google.comac10a2d2010-12-22 21:39:39 +0000135///////////////////////////////////////////////////////////////////////////////
136
bsalomon@google.comd302f142011-03-03 13:54:13 +0000137void SkGrClipIterator::reset(const SkClipStack& clipStack) {
138 fClipStack = &clipStack;
139 fIter.reset(clipStack);
140 // Gr has no notion of replace, skip to the
141 // last replace in the clip stack.
142 int lastReplace = 0;
143 int curr = 0;
144 while (NULL != (fCurr = fIter.next())) {
145 if (SkRegion::kReplace_Op == fCurr->fOp) {
146 lastReplace = curr;
147 }
148 ++curr;
149 }
150 fIter.reset(clipStack);
151 for (int i = 0; i < lastReplace+1; ++i) {
152 fCurr = fIter.next();
153 }
154}
155
156GrClipType SkGrClipIterator::getType() const {
157 GrAssert(!this->isDone());
scroggo7b118072011-03-23 15:04:26 +0000158 if (NULL == fCurr->fPath) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000159 return kRect_ClipType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000160 } else {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000161 return kPath_ClipType;
162 }
163}
164
165GrSetOp SkGrClipIterator::getOp() const {
166 // we skipped to the last "replace" op
167 // when this iter was reset.
168 // GrClip doesn't allow replace, so treat it as
169 // intersect.
170 GrSetOp skToGrOps[] = {
171 kDifference_SetOp, // kDifference_Op
172 kIntersect_SetOp, // kIntersect_Op
173 kUnion_SetOp, // kUnion_Op
174 kXor_SetOp, // kXOR_Op
175 kReverseDifference_SetOp, // kReverseDifference_Op
176 kIntersect_SetOp // kReplace_op
177 };
178 GR_STATIC_ASSERT(0 == SkRegion::kDifference_Op);
179 GR_STATIC_ASSERT(1 == SkRegion::kIntersect_Op);
180 GR_STATIC_ASSERT(2 == SkRegion::kUnion_Op);
181 GR_STATIC_ASSERT(3 == SkRegion::kXOR_Op);
182 GR_STATIC_ASSERT(4 == SkRegion::kReverseDifference_Op);
183 GR_STATIC_ASSERT(5 == SkRegion::kReplace_Op);
184 return skToGrOps[fCurr->fOp];
185}
186
187GrPathFill SkGrClipIterator::getPathFill() const {
188 switch (fCurr->fPath->getFillType()) {
189 case SkPath::kWinding_FillType:
190 return kWinding_PathFill;
191 case SkPath::kEvenOdd_FillType:
192 return kEvenOdd_PathFill;
193 case SkPath::kInverseWinding_FillType:
194 return kInverseWinding_PathFill;
195 case SkPath::kInverseEvenOdd_FillType:
196 return kInverseEvenOdd_PathFill;
197 default:
198 GrCrash("Unsupported path fill in clip.");
199 return kWinding_PathFill; // suppress warning
reed@google.comac10a2d2010-12-22 21:39:39 +0000200 }
201}
202
203///////////////////////////////////////////////////////////////////////////////
204
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000205GrPixelConfig SkGr::BitmapConfig2PixelConfig(SkBitmap::Config config,
reed@google.comac10a2d2010-12-22 21:39:39 +0000206 bool isOpaque) {
207 switch (config) {
208 case SkBitmap::kA8_Config:
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000209 return kAlpha_8_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000210 case SkBitmap::kIndex8_Config:
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000211 return kIndex_8_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000212 case SkBitmap::kRGB_565_Config:
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000213 return kRGB_565_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000214 case SkBitmap::kARGB_4444_Config:
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000215 return kRGBA_4444_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000216 case SkBitmap::kARGB_8888_Config:
217 if (isOpaque) {
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000218 return kRGBX_8888_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000219 } else {
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000220 return kRGBA_8888_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000221 }
222 default:
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000223 return kUnknown_GrPixelConfig;
reed@google.comac10a2d2010-12-22 21:39:39 +0000224 }
225}
226