blob: 5031c24548118b747c3251232cd35b1e0ca8691b [file] [log] [blame]
reed85d91782015-09-10 14:33:38 -07001/*
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"
reed7b6945b2015-09-24 00:50:58 -070010#include "SkCanvas.h"
reed85d91782015-09-10 14:33:38 -070011#include "SkData.h"
12#include "SkImageCacherator.h"
13#include "SkImagePriv.h"
14#include "SkPixelRef.h"
15#include "SkSurface.h"
16
17class SkImage_Generator : public SkImage_Base {
18public:
19 SkImage_Generator(SkImageCacherator* cache)
reedaf3fbfc2015-10-04 11:28:36 -070020 : INHERITED(cache->info().width(), cache->info().height(), cache->uniqueID())
reed85d91782015-09-10 14:33:38 -070021 , fCache(cache) // take ownership
22 {}
23
reed09553032015-11-23 12:32:16 -080024 bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY, CachingHint) const override;
reed85d91782015-09-10 14:33:38 -070025 const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const override;
26 SkData* onRefEncoded() const override;
27 bool isOpaque() const override { return fCache->info().isOpaque(); }
reed7b6945b2015-09-24 00:50:58 -070028 SkImage* onNewSubset(const SkIRect&) const override;
reed09553032015-11-23 12:32:16 -080029 bool getROPixels(SkBitmap*, CachingHint) const override;
bsalomonafa95e22015-10-12 10:39:46 -070030 GrTexture* asTextureRef(GrContext*, const GrTextureParams&) const override;
reed85d91782015-09-10 14:33:38 -070031 bool onIsLazyGenerated() const override { return true; }
32
33private:
34 SkAutoTDelete<SkImageCacherator> fCache;
35
36 typedef SkImage_Base INHERITED;
37};
38
39///////////////////////////////////////////////////////////////////////////////
40
reed85d91782015-09-10 14:33:38 -070041bool SkImage_Generator::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
reed09553032015-11-23 12:32:16 -080042 int srcX, int srcY, CachingHint chint) const {
reed85d91782015-09-10 14:33:38 -070043 SkBitmap bm;
reed09553032015-11-23 12:32:16 -080044 if (this->getROPixels(&bm, chint)) {
reed85d91782015-09-10 14:33:38 -070045 return bm.readPixels(dstInfo, dstPixels, dstRB, srcX, srcY);
46 }
47 return false;
48}
49
50const void* SkImage_Generator::onPeekPixels(SkImageInfo* infoPtr, size_t* rowBytesPtr) const {
51 return NULL;
52}
53
54SkData* SkImage_Generator::onRefEncoded() const {
55 return fCache->refEncoded();
56}
57
reed09553032015-11-23 12:32:16 -080058bool SkImage_Generator::getROPixels(SkBitmap* bitmap, CachingHint chint) const {
59 return fCache->lockAsBitmap(bitmap, this, chint);
reed85d91782015-09-10 14:33:38 -070060}
61
bsalomonafa95e22015-10-12 10:39:46 -070062GrTexture* SkImage_Generator::asTextureRef(GrContext* ctx, const GrTextureParams& params) const {
63 return fCache->lockAsTexture(ctx, params, this);
reed85d91782015-09-10 14:33:38 -070064}
65
reed7b6945b2015-09-24 00:50:58 -070066SkImage* SkImage_Generator::onNewSubset(const SkIRect& subset) const {
67 // TODO: make this lazy, by wrapping the subset inside a new generator or something
68 // For now, we do effectively what we did before, make it a raster
69
70 const SkImageInfo info = SkImageInfo::MakeN32(subset.width(), subset.height(),
71 this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
72 SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
73 if (!surface) {
74 return nullptr;
75 }
76 surface->getCanvas()->clear(0);
77 surface->getCanvas()->drawImage(this, SkIntToScalar(-subset.x()), SkIntToScalar(-subset.y()),
78 nullptr);
79 return surface->newImageSnapshot();
80}
81
reed85d91782015-09-10 14:33:38 -070082SkImage* SkImage::NewFromGenerator(SkImageGenerator* generator, const SkIRect* subset) {
83 SkImageCacherator* cache = SkImageCacherator::NewFromGenerator(generator, subset);
84 if (!cache) {
85 return nullptr;
86 }
mdempsky106b1242015-09-22 06:10:35 -070087 return new SkImage_Generator(cache);
reed85d91782015-09-10 14:33:38 -070088}