SkBitmapProcShader.h revision 87b0dd00cf9409c5fc990f5d0bb7c0df837f08da
1/*
2 * Copyright 2006 The Android Open Source Project
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#ifndef SkBitmapProcShader_DEFINED
9#define SkBitmapProcShader_DEFINED
10
11#include "SkShader.h"
12#include "SkSmallAllocator.h"
13
14struct SkBitmapProcState;
15class SkBitmapProvider;
16
17class SkBitmapProcShader : public SkShader {
18public:
19    SkBitmapProcShader(const SkBitmap& src, TileMode tx, TileMode ty,
20                       const SkMatrix* localMatrix = nullptr);
21
22    bool isOpaque() const override;
23
24    // SkBitmapProcShader stores bitmap coordinates in a 16bit buffer, as it
25    // communicates between its matrix-proc and its sampler-proc. Until we can
26    // widen that, we have to reject bitmaps that are larger.
27    static bool BitmapIsTooBig(const SkBitmap&);
28
29    SK_TO_STRING_OVERRIDE()
30    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBitmapProcShader)
31
32#if SK_SUPPORT_GPU
33    sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, const SkMatrix& viewM,
34                                                   const SkMatrix*, SkFilterQuality,
35                                                   SkSourceGammaTreatment) const override;
36#endif
37
38protected:
39    void flatten(SkWriteBuffer&) const override;
40    size_t onContextSize(const ContextRec& rec) const override {
41        return ContextSize(rec, fRawBitmap.info());
42    }
43    Context* onCreateContext(const ContextRec&, void* storage) const override;
44    bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode*) const override;
45
46    SkBitmap    fRawBitmap;
47    uint8_t     fTileModeX, fTileModeY;
48
49private:
50    friend class SkImageShader;
51
52    static size_t ContextSize(const ContextRec&, const SkImageInfo& srcInfo);
53    static Context* MakeContext(const SkShader&, TileMode tmx, TileMode tmy,
54                                const SkBitmapProvider&, const ContextRec&, void* storage);
55
56    typedef SkShader INHERITED;
57};
58
59enum {kSkBlitterContextSize = 3100};
60
61// Commonly used allocator. It currently is only used to allocate up to 3 objects. The total
62// bytes requested is calculated using one of our large shaders, its context size plus the size of
63// an Sk3DBlitter in SkDraw.cpp
64// Note that some contexts may contain other contexts (e.g. for compose shaders), but we've not
65// yet found a situation where the size below isn't big enough.
66typedef SkSmallAllocator<3, kSkBlitterContextSize> SkTBlitterAllocator;
67
68// If alloc is non-nullptr, it will be used to allocate the returned SkShader, and MUST outlive
69// the SkShader.
70sk_sp<SkShader> SkMakeBitmapShader(const SkBitmap& src, SkShader::TileMode, SkShader::TileMode,
71                                   const SkMatrix* localMatrix, SkTBlitterAllocator* alloc);
72
73#endif
74