tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SkImage_Picture.cpp (5181B)


      1 /*
      2 * Copyright 2023 Google LLC
      3 *
      4 * Use of this source code is governed by a BSD-style license that can be
      5 * found in the LICENSE file.
      6 */
      7 
      8 #include "src/image/SkImage_Picture.h"
      9 
     10 #include "include/core/SkCanvas.h"
     11 #include "include/core/SkColor.h"
     12 #include "include/core/SkColorSpace.h"
     13 #include "include/core/SkColorType.h"
     14 #include "include/core/SkImage.h"
     15 #include "include/core/SkImageGenerator.h"
     16 #include "include/core/SkImageInfo.h"
     17 #include "include/core/SkMatrix.h"
     18 #include "include/core/SkPicture.h"
     19 #include "include/core/SkRect.h"
     20 #include "include/core/SkSurfaceProps.h"
     21 #include "include/private/base/SkAssert.h"
     22 #include "include/private/base/SkMutex.h"
     23 #include "include/private/base/SkTFitsIn.h"
     24 #include "src/base/SkTLazy.h"
     25 #include "src/image/SkImageGeneratorPriv.h"
     26 #include "src/image/SkImage_Lazy.h"
     27 #include "src/image/SkPictureImageGenerator.h"
     28 
     29 #include <cstring>
     30 #include <memory>
     31 #include <utility>
     32 
     33 class SkPaint;
     34 struct SkISize;
     35 
     36 sk_sp<SkImage> SkImage_Picture::Make(sk_sp<SkPicture> picture, const SkISize& dimensions,
     37                                     const SkMatrix* matrix, const SkPaint* paint,
     38                                     SkImages::BitDepth bitDepth, sk_sp<SkColorSpace> colorSpace,
     39                                     SkSurfaceProps props) {
     40    auto gen = SkImageGenerators::MakeFromPicture(dimensions, std::move(picture), matrix, paint,
     41                                                  bitDepth, std::move(colorSpace), props);
     42 
     43    SkImage_Lazy::Validator validator(
     44            SharedGenerator::Make(std::move(gen)), nullptr, nullptr);
     45 
     46    return validator ? sk_make_sp<SkImage_Picture>(&validator) : nullptr;
     47 }
     48 
     49 const SkSurfaceProps* SkImage_Picture::props() const {
     50    auto pictureIG = static_cast<SkPictureImageGenerator*>(this->generator()->fGenerator.get());
     51    return &pictureIG->fProps;
     52 }
     53 
     54 void SkImage_Picture::replay(SkCanvas* canvas) const {
     55    auto sharedGenerator = this->generator();
     56    SkAutoMutexExclusive mutex(sharedGenerator->fMutex);
     57 
     58    auto pictureIG = static_cast<SkPictureImageGenerator*>(sharedGenerator->fGenerator.get());
     59    canvas->clear(SkColors::kTransparent);
     60    canvas->drawPicture(pictureIG->fPicture,
     61                        &pictureIG->fMatrix,
     62                        SkOptAddressOrNull(pictureIG->fPaint));
     63 }
     64 
     65 sk_sp<SkImage> SkImage_Picture::onMakeSubset(SkRecorder*,
     66                                             const SkIRect& subset,
     67                                             RequiredProperties) const {
     68    auto sharedGenerator = this->generator();
     69    auto pictureIG = static_cast<SkPictureImageGenerator*>(sharedGenerator->fGenerator.get());
     70 
     71    SkMatrix matrix = pictureIG->fMatrix;
     72    matrix.postTranslate(-subset.left(), -subset.top());
     73    SkImages::BitDepth bitDepth =
     74            this->colorType() == kRGBA_F16_SkColorType ? SkImages::BitDepth::kF16
     75                                                       : SkImages::BitDepth::kU8;
     76 
     77    return SkImage_Picture::Make(pictureIG->fPicture, subset.size(),
     78                                 &matrix, SkOptAddressOrNull(pictureIG->fPaint),
     79                                 bitDepth, this->refColorSpace(), pictureIG->fProps);
     80 }
     81 
     82 bool SkImage_Picture::getImageKeyValues(
     83        uint32_t keyValues[SkTiledImageUtils::kNumImageKeyValues]) const {
     84 
     85    auto sharedGenerator = this->generator();
     86    SkAutoMutexExclusive mutex(sharedGenerator->fMutex);
     87 
     88    auto pictureIG = static_cast<SkPictureImageGenerator*>(sharedGenerator->fGenerator.get());
     89    if (pictureIG->fPaint.has_value()) {
     90        // A full paint complicates the potential key too much.
     91        return false;
     92    }
     93 
     94    const SkImageInfo& ii = sharedGenerator->getInfo();
     95    if (!ii.colorSpace()->isSRGB()) {
     96        // We only return key values if the colorSpace is sRGB.
     97        return false;
     98    }
     99 
    100    const SkMatrix& m = pictureIG->fMatrix;
    101    if (!m.isIdentity() && !m.isTranslate()) {
    102        // To keep the key small we only cache simple (<= translation) matrices
    103        return false;
    104    }
    105 
    106    bool isU8 = ii.colorType() != kRGBA_F16_SkColorType;
    107    uint32_t pixelGeometry = this->props()->pixelGeometry();
    108    uint32_t surfacePropFlags = this->props()->flags();
    109    int width = ii.width();
    110    int height = ii.height();
    111    float transX = m.getTranslateX();
    112    float transY = m.getTranslateY();
    113 
    114    SkASSERT(pixelGeometry <= 4);
    115    SkASSERT(surfacePropFlags < 8);
    116    SkASSERT(SkTFitsIn<uint32_t>(width));
    117    SkASSERT(SkTFitsIn<uint32_t>(height));
    118    SkASSERT(sizeof(float) == sizeof(uint32_t));
    119 
    120    // The 0th slot usually holds either the SkBitmap's ID or the image's. In those two cases
    121    // slot #1 is zero so we can reuse the 0th slot here.
    122    keyValues[0] = (isU8 ? 0x1 : 0x0) |     // 1 bit
    123                   (pixelGeometry << 1) |   // 3 bits
    124                   (surfacePropFlags << 4); // 3 bits
    125    keyValues[1] = pictureIG->fPicture->uniqueID();
    126    SkASSERT(keyValues[1] != 0);    // Double check we don't collide w/ bitmap or image keys
    127    keyValues[2] = width;
    128    keyValues[3] = height;
    129    memcpy(&keyValues[4], &transX, sizeof(uint32_t));
    130    memcpy(&keyValues[5], &transY, sizeof(uint32_t));
    131    return true;
    132 }