1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#pragma once
17
18#include <SkBitmap.h>
19#include <SkColorSpace.h>
20#include <SkColorTable.h>
21#include <SkImageInfo.h>
22#include <SkPixelRef.h>
23#include <cutils/compiler.h>
24#include <ui/GraphicBuffer.h>
25
26namespace android {
27
28enum class PixelStorageType {
29    External,
30    Heap,
31    Ashmem,
32    Hardware,
33};
34
35namespace uirenderer {
36namespace renderthread {
37    class RenderThread;
38}
39}
40
41class PixelStorage;
42
43typedef void (*FreeFunc)(void* addr, void* context);
44
45class ANDROID_API Bitmap : public SkPixelRef {
46public:
47    static sk_sp<Bitmap> allocateHeapBitmap(SkBitmap* bitmap, SkColorTable* ctable);
48    static sk_sp<Bitmap> allocateHeapBitmap(const SkImageInfo& info);
49
50    static sk_sp<Bitmap> allocateHardwareBitmap(SkBitmap& bitmap);
51
52    static sk_sp<Bitmap> allocateAshmemBitmap(SkBitmap* bitmap, SkColorTable* ctable);
53    static sk_sp<Bitmap> allocateAshmemBitmap(size_t allocSize, const SkImageInfo& info,
54        size_t rowBytes, SkColorTable* ctable);
55
56    static sk_sp<Bitmap> createFrom(sp<GraphicBuffer> graphicBuffer);
57
58    static sk_sp<Bitmap> createFrom(const SkImageInfo&, SkPixelRef&);
59
60    static sk_sp<Bitmap> allocateHardwareBitmap(uirenderer::renderthread::RenderThread&,
61            SkBitmap& bitmap);
62
63    Bitmap(void* address, size_t allocSize, const SkImageInfo& info, size_t rowBytes,
64            SkColorTable* ctable);
65    Bitmap(void* address, void* context, FreeFunc freeFunc,
66            const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
67    Bitmap(void* address, int fd, size_t mappedSize, const SkImageInfo& info,
68            size_t rowBytes, SkColorTable* ctable);
69
70    int width() const { return info().width(); }
71    int height() const { return info().height(); }
72
73    // Can't mark as override since SkPixelRef::rowBytes isn't virtual
74    // but that's OK since we just want Bitmap to be able to rely
75    // on calling rowBytes() on an unlocked pixelref, which it will be
76    // doing on a Bitmap type, not a SkPixelRef, so static
77    // dispatching will do what we want.
78    size_t rowBytes() const { return mRowBytes; }
79
80    int rowBytesAsPixels() const {
81        return mRowBytes >> info().shiftPerPixel();
82    }
83
84    void reconfigure(const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
85    void reconfigure(const SkImageInfo& info);
86    void setColorSpace(sk_sp<SkColorSpace> colorSpace);
87    void setAlphaType(SkAlphaType alphaType);
88
89    void getSkBitmap(SkBitmap* outBitmap);
90
91    // Ugly hack: in case of hardware bitmaps, it sets nullptr as pixels pointer
92    // so it would crash if anyone tries to render this bitmap.
93    void getSkBitmapForShaders(SkBitmap* outBitmap);
94
95    int getAshmemFd() const;
96    size_t getAllocationByteCount() const;
97
98    void setHasHardwareMipMap(bool hasMipMap);
99    bool hasHardwareMipMap() const;
100
101    bool isOpaque() const {return info().isOpaque(); }
102    SkColorType colorType() const { return info().colorType(); }
103    void getBounds(SkRect* bounds) const;
104
105    bool readyToDraw() const {
106        return this->colorType() != kIndex_8_SkColorType || mColorTable;
107    }
108
109    bool isHardware() const {
110        return mPixelStorageType == PixelStorageType::Hardware;
111    }
112
113    GraphicBuffer* graphicBuffer();
114protected:
115    virtual bool onNewLockPixels(LockRec* rec) override;
116    virtual void onUnlockPixels() override { };
117    virtual size_t getAllocatedSizeInBytes() const override;
118private:
119    Bitmap(GraphicBuffer* buffer, const SkImageInfo& info);
120    virtual ~Bitmap();
121    void* getStorage() const;
122
123    PixelStorageType mPixelStorageType;
124
125    size_t mRowBytes = 0;
126    sk_sp<SkColorTable> mColorTable;
127    bool mHasHardwareMipMap = false;
128
129    union {
130        struct {
131            void* address;
132            void* context;
133            FreeFunc freeFunc;
134        } external;
135        struct {
136            void* address;
137            int fd;
138            size_t size;
139        } ashmem;
140        struct {
141            void* address;
142            size_t size;
143        } heap;
144        struct {
145            GraphicBuffer* buffer;
146        } hardware;
147    } mPixelStorage;
148};
149
150} //namespace android