1 /* 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 */ 31 static 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 += kGrColorTableSize; 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 66 GrTextureEntry* 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 GrTextureDesc desc = { 80 kNone_GrTextureFlags, 81 kNone_GrAALevel, 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 kGrColorTableSize; 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 117 void 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 136 GrClipType SkGrClipIterator::getType() const { 137 GrAssert(!this->isDone()); 138 if (NULL == fCurr->fPath) { 139 return kRect_ClipType; 140 } else { 141 return kPath_ClipType; 142 } 143 } 144 145 GrSetOp 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 167 GrPathFill 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 180 } 181 } 182 183 /////////////////////////////////////////////////////////////////////////////// 184 185 GrPixelConfig SkGr::BitmapConfig2PixelConfig(SkBitmap::Config config, 186 bool isOpaque) { 187 switch (config) { 188 case SkBitmap::kA8_Config: 189 return kAlpha_8_GrPixelConfig; 190 case SkBitmap::kIndex8_Config: 191 return kIndex_8_GrPixelConfig; 192 case SkBitmap::kRGB_565_Config: 193 return kRGB_565_GrPixelConfig; 194 case SkBitmap::kARGB_4444_Config: 195 return kRGBA_4444_GrPixelConfig; 196 case SkBitmap::kARGB_8888_Config: 197 if (isOpaque) { 198 return kRGBX_8888_GrPixelConfig; 199 } else { 200 return kRGBA_8888_GrPixelConfig; 201 } 202 default: 203 return kUnknown_GrPixelConfig; 204 } 205 } 206 207