1 /*
2  * Copyright (C) 2013 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 
17 #ifndef ANDROID_STRUCTURED_ALLOCATION_H
18 #define ANDROID_STRUCTURED_ALLOCATION_H
19 
20 #include "rsType.h"
21 
22 #if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB)
23 #include <ui/GraphicBuffer.h>
24 #include "rsGrallocConsumer.h"
25 #include "gui/CpuConsumer.h"
26 #include "gui/GLConsumer.h"
27 #else
28 struct ANativeWindowBuffer;
29 #endif
30 
31 // ---------------------------------------------------------------------------
32 namespace android {
33 
34 namespace renderscript {
35 
36 class Program;
37 
38 /*****************************************************************************
39  * CAUTION
40  *
41  * Any layout changes for this class may require a corresponding change to be
42  * made to frameworks/compile/libbcc/lib/ScriptCRT/rs_core.c, which contains
43  * a partial copy of the information below.
44  *
45  *****************************************************************************/
46 class Allocation : public ObjectBase {
47     // The graphics equivalent of malloc.  The allocation contains a structure of elements.
48 
49 public:
50     const static int MAX_LOD = 16;
51     // The mininum alignment requirement for RenderScript. Must be power of 2 and larger than 0.
52     const static size_t kMinimumRSAlignment = 16;
53     // The maximun number of Allocations that can share a single BufferQueue;
54     const static uint32_t MAX_NUM_ALLOC = 16;
55 
56     struct Hal {
57         void * drv;
58 
59         struct State {
60             const Type * type;
61 
62             uint32_t usageFlags;
63             RsAllocationMipmapControl mipmapControl;
64 
65             // Cached fields from the Type and Element
66             // to prevent pointer chasing in critical loops.
67             uint32_t yuv;
68             uint32_t elementSizeBytes;
69             bool hasMipmaps;
70             bool hasFaces;
71             bool hasReferences;
72             void * userProvidedPtr;
73             int32_t surfaceTextureID;
74             ANativeWindowBuffer *nativeBuffer;
75             int64_t timestamp;
76 
77             // Allocation adapter state
78             const Allocation *baseAlloc;
79             uint32_t originX;
80             uint32_t originY;
81             uint32_t originZ;
82             uint32_t originLOD;
83             uint32_t originFace;
84             uint32_t originArray[Type::mMaxArrays];
85         };
86         State state;
87 
88         struct DrvState {
89             struct LodState {
90                 void * mallocPtr;
91                 size_t stride;
92                 uint32_t dimX;
93                 uint32_t dimY;
94                 uint32_t dimZ;
95             } lod[android::renderscript::Allocation::MAX_LOD];
96             size_t faceOffset;
97             uint32_t lodCount;
98             uint32_t faceCount;
99 
100             struct YuvState {
101                 uint32_t shift;
102                 uint32_t step;
103             } yuv;
104 
105             int grallocFlags;
106             uint32_t dimArray[Type::mMaxArrays];
107         };
108         mutable DrvState drvState;
109 
110     };
111     Hal mHal;
112 
113     void operator delete(void* ptr);
114 
115     static Allocation * createAllocation(Context *rsc, const Type *, uint32_t usages,
116                                          RsAllocationMipmapControl mc = RS_ALLOCATION_MIPMAP_NONE,
117                                          void *ptr = 0);
118     static Allocation * createAllocationStrided(Context *rsc, const Type *, uint32_t usages,
119                                                 RsAllocationMipmapControl mc = RS_ALLOCATION_MIPMAP_NONE,
120                                                 void *ptr = 0, size_t byteAligned = 16);
121     static Allocation * createAdapter(Context *rsc, const Allocation *alloc, const Type *type);
122 
123 
124     virtual ~Allocation();
125     void updateCache();
126 
getType()127     const Type * getType() const {return mHal.state.type;}
128 
129     void syncAll(Context *rsc, RsAllocationUsageType src);
130 
131     void copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len);
132 
133     void resize1D(Context *rsc, uint32_t dimX);
134     void resize2D(Context *rsc, uint32_t dimX, uint32_t dimY);
135 
136     void data(Context *rsc, uint32_t xoff, uint32_t lod, uint32_t count, const void *data, size_t sizeBytes);
137     void data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
138               uint32_t w, uint32_t h, const void *data, size_t sizeBytes, size_t stride);
139     void data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t lod,
140               uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes, size_t stride);
141 
142     void read(Context *rsc, uint32_t xoff, uint32_t lod, uint32_t count, void *data, size_t sizeBytes);
143     void read(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
144               uint32_t w, uint32_t h, void *data, size_t sizeBytes, size_t stride);
145     void read(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t lod,
146               uint32_t w, uint32_t h, uint32_t d, void *data, size_t sizeBytes, size_t stride);
147 
148     void elementData(Context *rsc, uint32_t x, uint32_t y, uint32_t z,
149                      const void *data, uint32_t elementOff, size_t sizeBytes);
150 
151     void elementRead(Context *rsc, uint32_t x, uint32_t y, uint32_t z,
152                      void *data, uint32_t elementOff, size_t sizeBytes);
153 
154     void addProgramToDirty(const Program *);
155     void removeProgramToDirty(const Program *);
156 
157     virtual void dumpLOGV(const char *prefix) const;
158     virtual void serialize(Context *rsc, OStream *stream) const;
getClassId()159     virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_ALLOCATION; }
160     static Allocation *createFromStream(Context *rsc, IStream *stream);
161 
getIsScript()162     bool getIsScript() const {
163         return (mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) != 0;
164     }
getIsTexture()165     bool getIsTexture() const {
166         return (mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) != 0;
167     }
getIsRenderTarget()168     bool getIsRenderTarget() const {
169         return (mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) != 0;
170     }
getIsBufferObject()171     bool getIsBufferObject() const {
172         return (mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) != 0;
173     }
174 
175     void incRefs(const void *ptr, size_t ct, size_t startOff = 0) const;
176     void decRefs(const void *ptr, size_t ct, size_t startOff = 0) const;
177     virtual void callUpdateCacheObject(const Context *rsc, void *dstObj) const;
178     virtual bool freeChildren();
179 
180     void sendDirty(const Context *rsc) const;
getHasGraphicsMipmaps()181     bool getHasGraphicsMipmaps() const {
182         return mHal.state.mipmapControl != RS_ALLOCATION_MIPMAP_NONE;
183     }
184 
185     void setupGrallocConsumer(const Context *rsc, uint32_t numAlloc);
186     void shareBufferQueue(const Context *rsc, const Allocation *alloc);
187     void * getSurface(const Context *rsc);
188     void setSurface(const Context *rsc, RsNativeWindow sur);
189     void ioSend(const Context *rsc);
190     void ioReceive(const Context *rsc);
getTimeStamp()191     int64_t getTimeStamp() {return mHal.state.timestamp;}
192 
193     void adapterOffset(Context *rsc, const uint32_t *offsets, size_t len);
194 
195     void * getPointer(const Context *rsc, uint32_t lod, RsAllocationCubemapFace face,
196                       uint32_t z, uint32_t array, size_t *stride);
197 
198     void * getPointerUnchecked(uint32_t x, uint32_t y,
199                                uint32_t z = 0, uint32_t lod = 0,
200                                RsAllocationCubemapFace face = RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
201                                uint32_t a1 = 0, uint32_t a2 = 0, uint32_t a3 = 0, uint32_t a4 = 0) const {
202 
203         uint8_t * p = (uint8_t *) mHal.drvState.lod[lod].mallocPtr;
204         p += x * getType()->getElementSizeBytes();
205         p += y * mHal.drvState.lod[lod].stride;
206         p += z * mHal.drvState.lod[lod].stride * mHal.drvState.lod[lod].dimY;
207 
208         // Todo: arrays
209 
210         return p;
211     }
212 
213     bool hasSameDims(const Allocation *Other) const;
214 
215 protected:
216     Vector<const Program *> mToDirtyList;
217     ObjectBaseRef<const Type> mType;
setType(const Type * t)218     void setType(const Type *t) {
219         mType.set(t);
220         mHal.state.type = t;
221     }
222 
223 #if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB)
224     class NewBufferListener : public android::ConsumerBase::FrameAvailableListener {
225     public:
226         NewBufferListener(uint32_t numAlloc);
227         virtual ~NewBufferListener();
228         const android::renderscript::Context *rsc;
229         const android::renderscript::Allocation **alloc;
230 
231         virtual void onFrameAvailable(const BufferItem& item);
232     private:
233         uint32_t mNumAlloc;
234     };
235 
236     sp<NewBufferListener> mBufferListener;
237     sp< GrallocConsumer > mGrallocConsumer;
238     sp<IGraphicBufferProducer> mGraphicBufferProducer;
239     bool mBufferQueueInited = false;
240     uint32_t mCurrentIdx;
241 #endif
242 
243 
244 private:
245     void freeChildrenUnlocked();
246     Allocation(Context *rsc, const Type *, uint32_t usages, RsAllocationMipmapControl mc, void *ptr);
247     Allocation(Context *rsc, const Allocation *, const Type *);
248 
249     uint32_t getPackedSize() const;
250     static void writePackedData(Context *rsc, const Type *type, uint8_t *dst,
251                                 const uint8_t *src, bool dstPadded);
252     void unpackVec3Allocation(Context *rsc, const void *data, size_t dataSize);
253     void packVec3Allocation(Context *rsc, OStream *stream) const;
254 };
255 
256 }
257 }
258 #endif
259