Coverage Report

Created: 2024-09-14 07:19

/src/skia/src/image/SkSurface_Base.cpp
Line
Count
Source (jump to first uncovered line)
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/SkSurface_Base.h"
9
10
#include "include/core/SkBitmap.h"
11
#include "include/core/SkCanvas.h"
12
#include "include/core/SkCapabilities.h"
13
#include "include/core/SkColorSpace.h" // IWYU pragma: keep
14
#include "include/core/SkImage.h"
15
#include "include/core/SkImageInfo.h"
16
#include "include/core/SkPixmap.h"
17
#include "include/core/SkRect.h"
18
#include "include/core/SkRefCnt.h"
19
#include "include/core/SkScalar.h"
20
#include "include/core/SkSize.h"
21
#include "src/image/SkRescaleAndReadPixels.h"
22
23
#include <atomic>
24
#include <cstdint>
25
#include <memory>
26
27
class GrRecordingContext;
28
class SkPaint;
29
class SkSurfaceProps;
30
namespace skgpu { namespace graphite { class Recorder; } }
31
32
SkSurface_Base::SkSurface_Base(int width, int height, const SkSurfaceProps* props)
33
48.7k
        : SkSurface(width, height, props) {}
34
35
SkSurface_Base::SkSurface_Base(const SkImageInfo& info, const SkSurfaceProps* props)
36
36
        : SkSurface(info, props) {}
37
38
48.8k
SkSurface_Base::~SkSurface_Base() {
39
    // in case the canvas outsurvives us, we null the callback
40
48.8k
    if (fCachedCanvas) {
41
47.8k
        fCachedCanvas->setSurfaceBase(nullptr);
42
47.8k
    }
43
48.8k
}
44
45
0
GrRecordingContext* SkSurface_Base::onGetRecordingContext() const { return nullptr; }
46
47
0
skgpu::graphite::Recorder* SkSurface_Base::onGetRecorder() const { return nullptr; }
48
49
void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
50
0
                            const SkSamplingOptions& sampling, const SkPaint* paint) {
51
0
    auto image = this->makeImageSnapshot();
52
0
    if (image) {
53
0
        canvas->drawImage(image.get(), x, y, sampling, paint);
54
0
    }
55
0
}
56
57
void SkSurface_Base::onAsyncRescaleAndReadPixels(const SkImageInfo& info,
58
                                                 SkIRect origSrcRect,
59
                                                 SkSurface::RescaleGamma rescaleGamma,
60
                                                 RescaleMode rescaleMode,
61
                                                 SkSurface::ReadPixelsCallback callback,
62
0
                                                 SkSurface::ReadPixelsContext context) {
63
0
    SkBitmap src;
64
0
    SkPixmap peek;
65
0
    SkIRect srcRect;
66
0
    if (this->peekPixels(&peek)) {
67
0
        src.installPixels(peek);
68
0
        srcRect = origSrcRect;
69
0
    } else {
70
0
        src.setInfo(this->imageInfo().makeDimensions(origSrcRect.size()));
71
0
        src.allocPixels();
72
0
        if (!this->readPixels(src, origSrcRect.x(), origSrcRect.y())) {
73
0
            callback(context, nullptr);
74
0
            return;
75
0
        }
76
0
        srcRect = SkIRect::MakeSize(src.dimensions());
77
0
    }
78
0
    return SkRescaleAndReadPixels(src, info, srcRect, rescaleGamma, rescaleMode, callback,
79
0
                                  context);
80
0
}
81
82
void SkSurface_Base::onAsyncRescaleAndReadPixelsYUV420(
83
        SkYUVColorSpace yuvColorSpace, bool readAlpha, sk_sp<SkColorSpace> dstColorSpace,
84
        SkIRect srcRect, SkISize dstSize, RescaleGamma rescaleGamma, RescaleMode,
85
0
        ReadPixelsCallback callback, ReadPixelsContext context) {
86
    // TODO: Call non-YUV asyncRescaleAndReadPixels and then make our callback convert to YUV and
87
    // call client's callback.
88
0
    callback(context, nullptr);
89
0
}
90
91
56.1k
bool SkSurface_Base::outstandingImageSnapshot() const {
92
56.1k
    return fCachedImage && !fCachedImage->unique();
93
56.1k
}
94
95
242k
bool SkSurface_Base::aboutToDraw(ContentChangeMode mode) {
96
242k
    this->dirtyGenerationID();
97
98
242k
    SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this);
99
100
242k
    if (fCachedImage) {
101
        // the surface may need to fork its backend, if its sharing it with
102
        // the cached image. Note: we only call if there is an outstanding owner
103
        // on the image (besides us).
104
0
        bool unique = fCachedImage->unique();
105
0
        if (!unique) {
106
0
            if (!this->onCopyOnWrite(mode)) {
107
0
                return false;
108
0
            }
109
0
        }
110
111
        // regardless of copy-on-write, we must drop our cached image now, so
112
        // that the next request will get our new contents.
113
0
        fCachedImage.reset();
114
115
0
        if (unique) {
116
            // Our content isn't held by any image now, so we can consider that content mutable.
117
            // Raster surfaces need to be told it's safe to consider its pixels mutable again.
118
            // We make this call after the ->unref() so the subclass can assert there are no images.
119
0
            this->onRestoreBackingMutability();
120
0
        }
121
242k
    } else if (kDiscard_ContentChangeMode == mode) {
122
0
        this->onDiscard();
123
0
    }
124
242k
    return true;
125
242k
}
126
127
0
uint32_t SkSurface_Base::newGenerationID() {
128
0
    SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this);
129
0
    static std::atomic<uint32_t> nextID{1};
130
0
    return nextID.fetch_add(1, std::memory_order_relaxed);
131
0
}
Unexecuted instantiation: SkSurface_Base::newGenerationID()
Unexecuted instantiation: SkSurface_Base::newGenerationID()
132
133
0
sk_sp<const SkCapabilities> SkSurface_Base::onCapabilities() {
134
0
    return SkCapabilities::RasterBackend();
135
0
}