gfx/skia/trunk/src/core/SkMipMap.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /*
     2  * Copyright 2013 Google Inc.
     3  *
     4  * Use of this source code is governed by a BSD-style license that can be
     5  * found in the LICENSE file.
     6  */
     8 #include "SkMipMap.h"
     9 #include "SkBitmap.h"
    10 #include "SkColorPriv.h"
    12 static void downsampleby2_proc32(SkBitmap* dst, int x, int y,
    13                                  const SkBitmap& src) {
    14     x <<= 1;
    15     y <<= 1;
    16     const SkPMColor* p = src.getAddr32(x, y);
    17     const SkPMColor* baseP = p;
    18     SkPMColor c, ag, rb;
    20     c = *p; ag = (c >> 8) & 0xFF00FF; rb = c & 0xFF00FF;
    21     if (x < src.width() - 1) {
    22         p += 1;
    23     }
    24     c = *p; ag += (c >> 8) & 0xFF00FF; rb += c & 0xFF00FF;
    26     p = baseP;
    27     if (y < src.height() - 1) {
    28         p += src.rowBytes() >> 2;
    29     }
    30     c = *p; ag += (c >> 8) & 0xFF00FF; rb += c & 0xFF00FF;
    31     if (x < src.width() - 1) {
    32         p += 1;
    33     }
    34     c = *p; ag += (c >> 8) & 0xFF00FF; rb += c & 0xFF00FF;
    36     *dst->getAddr32(x >> 1, y >> 1) =
    37     ((rb >> 2) & 0xFF00FF) | ((ag << 6) & 0xFF00FF00);
    38 }
    40 static inline uint32_t expand16(U16CPU c) {
    41     return (c & ~SK_G16_MASK_IN_PLACE) | ((c & SK_G16_MASK_IN_PLACE) << 16);
    42 }
    44 // returns dirt in the top 16bits, but we don't care, since we only
    45 // store the low 16bits.
    46 static inline U16CPU pack16(uint32_t c) {
    47     return (c & ~SK_G16_MASK_IN_PLACE) | ((c >> 16) & SK_G16_MASK_IN_PLACE);
    48 }
    50 static void downsampleby2_proc16(SkBitmap* dst, int x, int y,
    51                                  const SkBitmap& src) {
    52     x <<= 1;
    53     y <<= 1;
    54     const uint16_t* p = src.getAddr16(x, y);
    55     const uint16_t* baseP = p;
    56     SkPMColor       c;
    58     c = expand16(*p);
    59     if (x < src.width() - 1) {
    60         p += 1;
    61     }
    62     c += expand16(*p);
    64     p = baseP;
    65     if (y < src.height() - 1) {
    66         p += src.rowBytes() >> 1;
    67     }
    68     c += expand16(*p);
    69     if (x < src.width() - 1) {
    70         p += 1;
    71     }
    72     c += expand16(*p);
    74     *dst->getAddr16(x >> 1, y >> 1) = (uint16_t)pack16(c >> 2);
    75 }
    77 static uint32_t expand4444(U16CPU c) {
    78     return (c & 0xF0F) | ((c & ~0xF0F) << 12);
    79 }
    81 static U16CPU collaps4444(uint32_t c) {
    82     return (c & 0xF0F) | ((c >> 12) & ~0xF0F);
    83 }
    85 static void downsampleby2_proc4444(SkBitmap* dst, int x, int y,
    86                                    const SkBitmap& src) {
    87     x <<= 1;
    88     y <<= 1;
    89     const uint16_t* p = src.getAddr16(x, y);
    90     const uint16_t* baseP = p;
    91     uint32_t        c;
    93     c = expand4444(*p);
    94     if (x < src.width() - 1) {
    95         p += 1;
    96     }
    97     c += expand4444(*p);
    99     p = baseP;
   100     if (y < src.height() - 1) {
   101         p += src.rowBytes() >> 1;
   102     }
   103     c += expand4444(*p);
   104     if (x < src.width() - 1) {
   105         p += 1;
   106     }
   107     c += expand4444(*p);
   109     *dst->getAddr16(x >> 1, y >> 1) = (uint16_t)collaps4444(c >> 2);
   110 }
   112 SkMipMap::Level* SkMipMap::AllocLevels(int levelCount, size_t pixelSize) {
   113     if (levelCount < 0) {
   114         return NULL;
   115     }
   116     int64_t size = sk_64_mul(levelCount + 1, sizeof(Level)) + pixelSize;
   117     if (!sk_64_isS32(size)) {
   118         return NULL;
   119     }
   120     return (Level*)sk_malloc_throw(sk_64_asS32(size));
   121 }
   123 SkMipMap* SkMipMap::Build(const SkBitmap& src) {
   124     void (*proc)(SkBitmap* dst, int x, int y, const SkBitmap& src);
   126     const SkBitmap::Config config = src.config();
   127     switch (config) {
   128         case SkBitmap::kARGB_8888_Config:
   129             proc = downsampleby2_proc32;
   130             break;
   131         case SkBitmap::kRGB_565_Config:
   132             proc = downsampleby2_proc16;
   133             break;
   134         case SkBitmap::kARGB_4444_Config:
   135             proc = downsampleby2_proc4444;
   136             break;
   137         case SkBitmap::kIndex8_Config:
   138         case SkBitmap::kA8_Config:
   139         default:
   140             return NULL; // don't build mipmaps for these configs
   141     }
   143     SkAutoLockPixels alp(src);
   144     if (!src.readyToDraw()) {
   145         return NULL;
   146     }
   148     // whip through our loop to compute the exact size needed
   149     size_t  size = 0;
   150     int     countLevels = 0;
   151     {
   152         int width = src.width();
   153         int height = src.height();
   154         for (;;) {
   155             width >>= 1;
   156             height >>= 1;
   157             if (0 == width || 0 == height) {
   158                 break;
   159             }
   160             size += SkBitmap::ComputeRowBytes(config, width) * height;
   161             countLevels += 1;
   162         }
   163     }
   164     if (0 == countLevels) {
   165         return NULL;
   166     }
   168     Level* levels = SkMipMap::AllocLevels(countLevels, size);
   169     if (NULL == levels) {
   170         return NULL;
   171     }
   173     uint8_t*    baseAddr = (uint8_t*)&levels[countLevels];
   174     uint8_t*    addr = baseAddr;
   175     int         width = src.width();
   176     int         height = src.height();
   177     uint32_t    rowBytes;
   178     SkBitmap    srcBM(src);
   180     for (int i = 0; i < countLevels; ++i) {
   181         width >>= 1;
   182         height >>= 1;
   183         rowBytes = SkToU32(SkBitmap::ComputeRowBytes(config, width));
   185         levels[i].fPixels   = addr;
   186         levels[i].fWidth    = width;
   187         levels[i].fHeight   = height;
   188         levels[i].fRowBytes = rowBytes;
   189         levels[i].fScale    = (float)width / src.width();
   191         SkBitmap dstBM;
   192         dstBM.setConfig(config, width, height, rowBytes);
   193         dstBM.setPixels(addr);
   195         srcBM.lockPixels();
   196         for (int y = 0; y < height; y++) {
   197             for (int x = 0; x < width; x++) {
   198                 proc(&dstBM, x, y, srcBM);
   199             }
   200         }
   201         srcBM.unlockPixels();
   203         srcBM = dstBM;
   204         addr += height * rowBytes;
   205     }
   206     SkASSERT(addr == baseAddr + size);
   208     return SkNEW_ARGS(SkMipMap, (levels, countLevels, size));
   209 }
   211 ///////////////////////////////////////////////////////////////////////////////
   213 //static int gCounter;
   215 SkMipMap::SkMipMap(Level* levels, int count, size_t size)
   216     : fSize(size), fLevels(levels), fCount(count) {
   217     SkASSERT(levels);
   218     SkASSERT(count > 0);
   219 //    SkDebugf("mips %d\n", ++gCounter);
   220 }
   222 SkMipMap::~SkMipMap() {
   223     sk_free(fLevels);
   224 //    SkDebugf("mips %d\n", --gCounter);
   225 }
   227 static SkFixed compute_level(SkScalar scale) {
   228     SkFixed s = SkAbs32(SkScalarToFixed(SkScalarInvert(scale)));
   230     if (s < SK_Fixed1) {
   231         return 0;
   232     }
   233     int clz = SkCLZ(s);
   234     SkASSERT(clz >= 1 && clz <= 15);
   235     return SkIntToFixed(15 - clz) + ((unsigned)(s << (clz + 1)) >> 16);
   236 }
   238 bool SkMipMap::extractLevel(SkScalar scale, Level* levelPtr) const {
   239     if (scale >= SK_Scalar1) {
   240         return false;
   241     }
   243     int level = compute_level(scale) >> 16;
   244     SkASSERT(level >= 0);
   245     if (level <= 0) {
   246         return false;
   247     }
   249     if (level > fCount) {
   250         level = fCount;
   251     }
   252     if (levelPtr) {
   253         *levelPtr = fLevels[level - 1];
   254     }
   255     return true;
   256 }

mercurial