blob: 8849db767a3e34d6fe40f402e7acc88c62607af6 [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].
22
23 At the moment Ganesh only supports 8bit version. If Ganesh allowed we others
24 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.
27
28 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());
33
34 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;
42
43 memcpy(dst, ctable->lockColors(), ctable->count() * sizeof(SkPMColor));
44 ctable->unlockColors(false);
45
46 // always skip a full 256 number of entries, even if we memcpy'd fewer
47 dst += GrGpu::kColorTableSize;
48
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
66GrTextureEntry* sk_gr_create_bitmap_texture(GrContext* ctx,
67 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;
78
79 GrGpu::TextureDesc desc = {
80 0,
81 GrGpu::kNone_AALevel,
82 bitmap->width(),
83 bitmap->height(),
84 SkGr::Bitmap2PixelConfig(*bitmap)
85 };
86
87 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())) {
92 size_t imagesize = bitmap->width() * bitmap->height() +
93 GrGpu::kColorTableSize;
94 SkAutoMalloc storage(imagesize);
95
96 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 }
108 }
109
110 desc.fFormat = SkGr::Bitmap2PixelConfig(*bitmap);
111 return ctx->createAndLockTexture(key, sampler, desc, bitmap->getPixels(),
112 bitmap->rowBytes());
113}
114
115////////////////////////////////////////////////////////////////////////////////
116
117void sk_gr_set_paint(GrContext* ctx, const SkPaint& paint, bool justAlpha) {
118 ctx->setDither(paint.isDither());
119 ctx->setAntiAlias(paint.isAntiAlias());
120
121 if (justAlpha) {
122 ctx->setAlpha(paint.getAlpha());
123 } else {
124 ctx->setColor(SkGr::SkColor2GrColor(paint.getColor()));
125 }
126
127 SkXfermode::Coeff sm = SkXfermode::kOne_Coeff;
128 SkXfermode::Coeff dm = SkXfermode::kISA_Coeff;
129
130 SkXfermode* mode = paint.getXfermode();
131 if (mode) {
132 mode->asCoeff(&sm, &dm);
133 }
134 ctx->setBlendFunc(sk_blend_to_grblend(sm), sk_blend_to_grblend(dm));
135}
136
137////////////////////////////////////////////////////////////////////////////////
138
139SkGrPathIter::Command SkGrPathIter::next(GrPoint pts[]) {
140 GrAssert(NULL != pts);
141#if SK_SCALAR_IS_GR_SCALAR
142 return sk_path_verb_to_gr_path_command(fIter.next((SkPoint*)pts));
143#else
144 Command cmd = sk_path_verb_to_gr_path_command(fIter.next(fPoints));
145 int n = NumCommandPoints(cmd);
146 for (int i = 0; i < n; ++i) {
147 pts[i].fX = SkScalarToGrScalar(fPoints[i].fX);
148 pts[i].fY = SkScalarToGrScalar(fPoints[i].fY);
149 }
150 return cmd;
151#endif
152}
153
154SkGrPathIter::Command SkGrPathIter::next() {
155 return sk_path_verb_to_gr_path_command(fIter.next(NULL));
156}
157
158void SkGrPathIter::rewind() {
159 fIter.setPath(fPath, false);
160}
161
162GrPathIter::ConvexHint SkGrPathIter::hint() const {
163 return fPath.isConvex() ? GrPathIter::kConvex_ConvexHint :
164 GrPathIter::kNone_ConvexHint;
165}
166
167///////////////////////////////////////////////////////////////////////////////
168
169void SkGrClipIterator::computeBounds(GrIRect* bounds) {
170 const SkRegion* rgn = fIter.rgn();
171 if (rgn) {
172 SkGr::SetIRect(bounds, rgn->getBounds());
173 } else {
174 bounds->setEmpty();
175 }
176}
177
178///////////////////////////////////////////////////////////////////////////////
179
180GrTexture::PixelConfig SkGr::BitmapConfig2PixelConfig(SkBitmap::Config config,
181 bool isOpaque) {
182 switch (config) {
183 case SkBitmap::kA8_Config:
184 return GrTexture::kAlpha_8_PixelConfig;
185 case SkBitmap::kIndex8_Config:
186 return GrTexture::kIndex_8_PixelConfig;
187 case SkBitmap::kRGB_565_Config:
188 return GrTexture::kRGB_565_PixelConfig;
189 case SkBitmap::kARGB_4444_Config:
190 return GrTexture::kRGBA_4444_PixelConfig;
191 case SkBitmap::kARGB_8888_Config:
192 if (isOpaque) {
193 return GrTexture::kRGBX_8888_PixelConfig;
194 } else {
195 return GrTexture::kRGBA_8888_PixelConfig;
196 }
197 default:
198 return GrTexture::kUnknown_PixelConfig;
199 }
200}
201
202void SkGr::AbandonAllTextures(GrContext* ctx) {
203 ctx->abandonAllTextures();
204}
205
206