Home | History | Annotate | Download | only in gpu
      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