rs_hal.h revision c794cd56e46408e08862c42a022090e323684197
1895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/*
2895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * Copyright (C) 2011 The Android Open Source Project
3895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *
4895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * Licensed under the Apache License, Version 2.0 (the "License");
5895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * you may not use this file except in compliance with the License.
6895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * You may obtain a copy of the License at
7895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *
8895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *      http://www.apache.org/licenses/LICENSE-2.0
9895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *
10895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * Unless required by applicable law or agreed to in writing, software
11895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * distributed under the License is distributed on an "AS IS" BASIS,
12895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * See the License for the specific language governing permissions and
14895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * limitations under the License.
15895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall */
16895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
17895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#ifndef RS_HAL_H
18895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#define RS_HAL_H
19895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
20895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include <RenderScriptDefines.h>
21895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
22895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallnamespace android {
23895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallnamespace renderscript {
24895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
25895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallclass Context;
26895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallclass ObjectBase;
27895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallclass Element;
28895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallclass Type;
29895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallclass Allocation;
30895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallclass Script;
31895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallclass ScriptC;
32895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallclass Path;
33895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallclass Program;
34895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallclass ProgramStore;
35895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallclass ProgramRaster;
36895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallclass ProgramVertex;
37895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallclass ProgramFragment;
38895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallclass Mesh;
39895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallclass Sampler;
40895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallclass FBOCache;
41895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
42895401859313187f15a800e62d43e6bcbf48fadaJP Abgralltypedef void *(*RsHalSymbolLookupFunc)(void *usrptr, char const *symbolName);
43895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
44895401859313187f15a800e62d43e6bcbf48fadaJP Abgralltypedef struct {
45895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    const void *in;
46895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    void *out;
47895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    const void *usr;
48895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    size_t usr_len;
49895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    uint32_t x;
50895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    uint32_t y;
51895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    uint32_t z;
52895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    uint32_t lod;
53895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    RsAllocationCubemapFace face;
54895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    uint32_t ar[16];
55895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall} RsForEachStubParamStruct;
56895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
57895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/**
58895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * Script management functions
59895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall */
60895401859313187f15a800e62d43e6bcbf48fadaJP Abgralltypedef struct {
61895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    bool (*initGraphics)(const Context *);
62895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    void (*shutdownGraphics)(const Context *);
63895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    bool (*setSurface)(const Context *, uint32_t w, uint32_t h, RsNativeWindow);
64895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    void (*swap)(const Context *);
65895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
66895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    void (*shutdownDriver)(Context *);
67895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    void (*getVersion)(unsigned int *major, unsigned int *minor);
68895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    void (*setPriority)(const Context *, int32_t priority);
69895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
70895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
71895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
72895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    struct {
73895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        bool (*init)(const Context *rsc, ScriptC *s,
74895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                     char const *resName,
75895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                     char const *cacheDir,
76895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                     uint8_t const *bitcode,
77895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                     size_t bitcodeSize,
78895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                     uint32_t flags);
79895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
80895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*invokeFunction)(const Context *rsc, Script *s,
81895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                               uint32_t slot,
82895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                               const void *params,
83895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                               size_t paramLength);
84895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        int (*invokeRoot)(const Context *rsc, Script *s);
85895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*invokeForEach)(const Context *rsc,
86895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                              Script *s,
87895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                              uint32_t slot,
88895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                              const Allocation * ain,
89895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                              Allocation * aout,
90895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                              const void * usr,
91895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                              uint32_t usrLen,
92895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                              const RsScriptCall *sc);
93895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*invokeInit)(const Context *rsc, Script *s);
94895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*invokeFreeChildren)(const Context *rsc, Script *s);
95895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
96895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*setGlobalVar)(const Context *rsc, const Script *s,
97895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                             uint32_t slot,
98895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                             void *data,
99895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                             size_t dataLength);
100895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*setGlobalBind)(const Context *rsc, const Script *s,
101895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                              uint32_t slot,
102895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                              void *data);
103895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*setGlobalObj)(const Context *rsc, const Script *s,
104895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                             uint32_t slot,
105895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                             ObjectBase *data);
106895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
107895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*destroy)(const Context *rsc, Script *s);
108895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    } script;
109895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
110895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    struct {
111895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        bool (*init)(const Context *rsc, Allocation *alloc, bool forceZero);
112895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*destroy)(const Context *rsc, Allocation *alloc);
113895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
114895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*resize)(const Context *rsc, const Allocation *alloc, const Type *newType,
115895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                       bool zeroNew);
116895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*syncAll)(const Context *rsc, const Allocation *alloc, RsAllocationUsageType src);
117895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*markDirty)(const Context *rsc, const Allocation *alloc);
118895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        int32_t (*initSurfaceTexture)(const Context *rsc, const Allocation *alloc);
119895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
120895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*data1D)(const Context *rsc, const Allocation *alloc,
121895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                       uint32_t xoff, uint32_t lod, uint32_t count,
122895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                       const void *data, size_t sizeBytes);
123895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*data2D)(const Context *rsc, const Allocation *alloc,
124895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                       uint32_t xoff, uint32_t yoff, uint32_t lod,
125895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                       RsAllocationCubemapFace face, uint32_t w, uint32_t h,
126895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                       const void *data, size_t sizeBytes);
127895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*data3D)(const Context *rsc, const Allocation *alloc,
128895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                       uint32_t xoff, uint32_t yoff, uint32_t zoff,
129895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                       uint32_t lod, RsAllocationCubemapFace face,
130895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                       uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes);
131895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
132895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        // Allocation to allocation copies
133895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*allocData1D)(const Context *rsc,
134895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                            const Allocation *dstAlloc,
135895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                            uint32_t dstXoff, uint32_t dstLod, uint32_t count,
136895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                            const Allocation *srcAlloc, uint32_t srcXoff, uint32_t srcLod);
137895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*allocData2D)(const Context *rsc,
138895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                            const Allocation *dstAlloc,
139895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                            uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod,
140895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                            RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h,
141895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                            const Allocation *srcAlloc,
142895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                            uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
143895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                            RsAllocationCubemapFace srcFace);
144895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*allocData3D)(const Context *rsc,
145895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                            const Allocation *dstAlloc,
146895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                            uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff,
147895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                            uint32_t dstLod, RsAllocationCubemapFace dstFace,
148895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                            uint32_t w, uint32_t h, uint32_t d,
149895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                            const Allocation *srcAlloc,
150895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                            uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff,
151895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                            uint32_t srcLod, RsAllocationCubemapFace srcFace);
152895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
153895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*elementData1D)(const Context *rsc, const Allocation *alloc, uint32_t x,
154895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                              const void *data, uint32_t elementOff, size_t sizeBytes);
155895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*elementData2D)(const Context *rsc, const Allocation *alloc, uint32_t x, uint32_t y,
156895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                              const void *data, uint32_t elementOff, size_t sizeBytes);
157895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
158895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
159895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    } allocation;
160895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
161895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    struct {
162895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        bool (*init)(const Context *rsc, const ProgramStore *ps);
163895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*setActive)(const Context *rsc, const ProgramStore *ps);
164895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*destroy)(const Context *rsc, const ProgramStore *ps);
165895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    } store;
166895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
167895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    struct {
168895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        bool (*init)(const Context *rsc, const ProgramRaster *ps);
169895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*setActive)(const Context *rsc, const ProgramRaster *ps);
170895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*destroy)(const Context *rsc, const ProgramRaster *ps);
171895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    } raster;
172895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
173895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    struct {
174895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        bool (*init)(const Context *rsc, const ProgramVertex *pv,
175895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                     const char* shader, size_t shaderLen);
176895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*setActive)(const Context *rsc, const ProgramVertex *pv);
177895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*destroy)(const Context *rsc, const ProgramVertex *pv);
178895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    } vertex;
179895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
180895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    struct {
181895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        bool (*init)(const Context *rsc, const ProgramFragment *pf,
182895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                     const char* shader, size_t shaderLen);
183895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*setActive)(const Context *rsc, const ProgramFragment *pf);
184895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*destroy)(const Context *rsc, const ProgramFragment *pf);
185895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    } fragment;
186895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
187895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    struct {
188895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        bool (*init)(const Context *rsc, const Mesh *m);
189895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*draw)(const Context *rsc, const Mesh *m, uint32_t primIndex, uint32_t start, uint32_t len);
190895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*destroy)(const Context *rsc, const Mesh *m);
191895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    } mesh;
192895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
193895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    struct {
194895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        bool (*initStatic)(const Context *rsc, const Path *m, const Allocation *vtx, const Allocation *loops);
195895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        bool (*initDynamic)(const Context *rsc, const Path *m);
196895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*draw)(const Context *rsc, const Path *m);
197895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*destroy)(const Context *rsc, const Path *m);
198895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    } path;
199895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
200895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    struct {
201895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        bool (*init)(const Context *rsc, const Sampler *m);
202895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*destroy)(const Context *rsc, const Sampler *m);
203895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    } sampler;
204895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
205895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    struct {
206895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        bool (*init)(const Context *rsc, const FBOCache *fb);
207895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*setActive)(const Context *rsc, const FBOCache *fb);
208895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        void (*destroy)(const Context *rsc, const FBOCache *fb);
209895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    } framebuffer;
210895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
211895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall} RsdHalFunctions;
212895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
213895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
214895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall}
215895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall}
216895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
217895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
218895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallbool rsdHalInit(android::renderscript::Context *, uint32_t version_major, uint32_t version_minor);
219895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
220895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#endif
221895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
222895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall