SkImage_Generator.cpp revision 7b8400dad2f82dcc6ed3c7cc1707ebaf85f04840
1/*
2 * Copyright 2015 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 */
7
8#include "SkImage_Base.h"
9#include "SkBitmap.h"
10#include "SkData.h"
11#include "SkImageCacherator.h"
12#include "SkImagePriv.h"
13#include "SkPixelRef.h"
14
15class SkImage_Generator : public SkImage_Base {
16public:
17    SkImage_Generator(SkImageCacherator::Validator* validator)
18        : INHERITED(validator->fInfo.width(), validator->fInfo.height(), validator->fUniqueID)
19        , fCache(validator)
20    {}
21
22    virtual SkImageInfo onImageInfo() const override {
23        return fCache.info();
24    }
25    SkAlphaType onAlphaType() const override {
26        return fCache.info().alphaType();
27    }
28
29    bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY, CachingHint) const override;
30    SkImageCacherator* peekCacherator() const override { return &fCache; }
31    SkData* onRefEncoded(GrContext*) const override;
32    sk_sp<SkImage> onMakeSubset(const SkIRect&) const override;
33    bool getROPixels(SkBitmap*, CachingHint) const override;
34    GrTexture* asTextureRef(GrContext*, const GrTextureParams&,
35                            SkDestinationSurfaceColorMode) const override;
36    bool onIsLazyGenerated() const override { return true; }
37
38private:
39    mutable SkImageCacherator fCache;
40
41    typedef SkImage_Base INHERITED;
42};
43
44///////////////////////////////////////////////////////////////////////////////
45
46bool SkImage_Generator::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
47                                     int srcX, int srcY, CachingHint chint) const {
48    SkBitmap bm;
49    if (kDisallow_CachingHint == chint) {
50        if (fCache.lockAsBitmapOnlyIfAlreadyCached(&bm)) {
51            return bm.readPixels(dstInfo, dstPixels, dstRB, srcX, srcY);
52        } else {
53            // Try passing the caller's buffer directly down to the generator. If this fails we
54            // may still succeed in the general case, as the generator may prefer some other
55            // config, which we could then convert via SkBitmap::readPixels.
56            if (fCache.directGeneratePixels(dstInfo, dstPixels, dstRB, srcX, srcY)) {
57                return true;
58            }
59            // else fall through
60        }
61    }
62
63    if (this->getROPixels(&bm, chint)) {
64        return bm.readPixels(dstInfo, dstPixels, dstRB, srcX, srcY);
65    }
66    return false;
67}
68
69SkData* SkImage_Generator::onRefEncoded(GrContext* ctx) const {
70    return fCache.refEncoded(ctx);
71}
72
73bool SkImage_Generator::getROPixels(SkBitmap* bitmap, CachingHint chint) const {
74    return fCache.lockAsBitmap(bitmap, this, chint);
75}
76
77GrTexture* SkImage_Generator::asTextureRef(GrContext* ctx, const GrTextureParams& params,
78                                           SkDestinationSurfaceColorMode colorMode) const {
79    return fCache.lockAsTexture(ctx, params, colorMode, this);
80}
81
82sk_sp<SkImage> SkImage_Generator::onMakeSubset(const SkIRect& subset) const {
83    SkASSERT(fCache.info().bounds().contains(subset));
84    SkASSERT(fCache.info().bounds() != subset);
85
86    const SkIRect generatorSubset = subset.makeOffset(fCache.fOrigin.x(), fCache.fOrigin.y());
87    SkImageCacherator::Validator validator(fCache.fSharedGenerator, &generatorSubset);
88    return validator ? sk_sp<SkImage>(new SkImage_Generator(&validator)) : nullptr;
89}
90
91sk_sp<SkImage> SkImage::MakeFromGenerator(SkImageGenerator* generator, const SkIRect* subset) {
92    SkImageCacherator::Validator validator(SkImageCacherator::SharedGenerator::Make(generator),
93                                           subset);
94
95    return validator ? sk_make_sp<SkImage_Generator>(&validator) : nullptr;
96}
97