Project

General

Profile

Download (14.1 KB) Statistics
| Branch: | Revision:

library / src / main / java / org / distorted / library / effectqueue / EffectQueue.java @ 644c21f2

1 d333eb6b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4 46b572b5 Leszek Koltunski
// This file is part of Distorted.                                                               //
5 d333eb6b Leszek Koltunski
//                                                                                               //
6 46b572b5 Leszek Koltunski
// Distorted is free software: you can redistribute it and/or modify                             //
7 d333eb6b Leszek Koltunski
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11 46b572b5 Leszek Koltunski
// Distorted is distributed in the hope that it will be useful,                                  //
12 d333eb6b Leszek Koltunski
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17 46b572b5 Leszek Koltunski
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18 d333eb6b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20 809dcae3 Leszek Koltunski
package org.distorted.library.effectqueue;
21 6a06a912 Leszek Koltunski
22 fe82a979 Leszek Koltunski
import org.distorted.library.effect.Effect;
23 da9b3f07 Leszek Koltunski
import org.distorted.library.effect.EffectName;
24
import org.distorted.library.effect.EffectType;
25 7602a827 Leszek Koltunski
import org.distorted.library.main.DistortedLibrary;
26
import org.distorted.library.main.InternalMaster;
27 a4835695 Leszek Koltunski
28 26a4e5f6 leszek
import java.util.ArrayList;
29 3417ab4e leszek
import java.util.HashMap;
30 6a06a912 Leszek Koltunski
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32 809dcae3 Leszek Koltunski
/**
33
 * Not part of public API, do not document
34
 *
35
 * @y.exclude
36
 */
37 7602a827 Leszek Koltunski
public abstract class EffectQueue implements InternalMaster.Slave
38 6a06a912 Leszek Koltunski
  {
39 809dcae3 Leszek Koltunski
  static final int MAIN_VARIANTS = 3; // Number of Main program variants (ATM 3: MAIN, MAIN OIT, PREPROCESS)
40
41 1418a5eb Leszek Koltunski
  private static final int CREATE = 0;
42
  private static final int ATTACH = 1;
43
  private static final int DETACH = 2;
44
  private static final int DETALL = 3;
45 26a4e5f6 leszek
46 8bfefd68 Leszek Koltunski
  int mNumEffects;              // 'ToBe' will be more than mNumEffects if doWork() hasn't
47
  private int mNumEffectsToBe;  // added them yet (or less if it hasn't removed some yet)
48 13981586 Leszek Koltunski
  float[] mUniforms;
49
  long[] mCurrentDuration;
50
  Effect[] mEffects;
51
  int[] mName;
52
  long mTime=0;
53 71887484 Leszek Koltunski
54 13981586 Leszek Koltunski
  private static int[] mMax = new int[EffectType.LENGTH];
55 3417ab4e leszek
  private static long mNextID;
56
  private static HashMap<ArrayList<Long>,Long> mMapID = new HashMap<>(); // maps lists of Effect IDs (longs) to a
57
                                                                         // single long - the queue ID.
58 26a4e5f6 leszek
  private long mID;
59 15aa7d94 Leszek Koltunski
  private int mIndex;
60 06dbccad Leszek Koltunski
  private boolean mCreated;
61 71887484 Leszek Koltunski
62 26a4e5f6 leszek
  private class Job
63
    {
64
    int type;
65 1418a5eb Leszek Koltunski
    int num;
66 26a4e5f6 leszek
    boolean notify;
67
    Effect effect;
68
69 1418a5eb Leszek Koltunski
    Job(int t, int m, boolean n, Effect e)
70 26a4e5f6 leszek
      {
71
      type  = t;
72 1418a5eb Leszek Koltunski
      num   = m;
73 26a4e5f6 leszek
      notify= n;
74
      effect= e;
75
      }
76
    }
77
78
  private ArrayList<Job> mJobs = new ArrayList<>();
79
80 6a06a912 Leszek Koltunski
  static
81
    {
82 7b8086eb Leszek Koltunski
    onDestroy();
83 6a06a912 Leszek Koltunski
    }
84
  
85
///////////////////////////////////////////////////////////////////////////////////////////////////
86
   
87 20dbec0e Leszek Koltunski
  EffectQueue(int numUniforms, int index)
88 6a06a912 Leszek Koltunski
    {
89 06dbccad Leszek Koltunski
    mCreated            = false;
90 26a4e5f6 leszek
    mID                 = 0;
91 fe6fe99a leszek
    mNumEffects         = 0;
92 26a4e5f6 leszek
    mNumEffectsToBe     = 0;
93 fe6fe99a leszek
    mIndex              = index;
94 1e438fc7 Leszek Koltunski
95 1418a5eb Leszek Koltunski
    mJobs.add(new Job(CREATE,numUniforms,false,null));  // create the stuff that depends on max number
96 7602a827 Leszek Koltunski
    InternalMaster.newSlave(this);                     // of uniforms later, on first render.
97 6a06a912 Leszek Koltunski
    }
98
99 a0397f32 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
100
101 20dbec0e Leszek Koltunski
  public static void allocateQueues(EffectQueue[] queues, EffectQueue[] from, int flags)
102 a0397f32 Leszek Koltunski
    {
103 20dbec0e Leszek Koltunski
    queues[0] = (flags & DistortedLibrary.CLONE_MATRIX     ) != 0 ? from[0] : new EffectQueueMatrix();
104
    queues[1] = (flags & DistortedLibrary.CLONE_VERTEX     ) != 0 ? from[1] : new EffectQueueVertex();
105
    queues[2] = (flags & DistortedLibrary.CLONE_FRAGMENT   ) != 0 ? from[2] : new EffectQueueFragment();
106
    queues[3] = (flags & DistortedLibrary.CLONE_POSTPROCESS) != 0 ? from[3] : new EffectQueuePostprocess();
107 a0397f32 Leszek Koltunski
    }
108
109
///////////////////////////////////////////////////////////////////////////////////////////////////
110
111 644c21f2 Leszek Koltunski
  public static void compute(EffectQueue[] queues, long currTime)
112 a0397f32 Leszek Koltunski
    {
113
    ((EffectQueueMatrix     )queues[0]).compute(currTime);
114 644c21f2 Leszek Koltunski
    ((EffectQueueVertex     )queues[1]).compute(currTime);
115
    ((EffectQueueFragment   )queues[2]).compute(currTime);
116 a0397f32 Leszek Koltunski
    ((EffectQueuePostprocess)queues[3]).compute(currTime);
117
    }
118
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120
121 809dcae3 Leszek Koltunski
  public static void send( EffectQueue[] queues, int width, int height, float distance, float mipmap,
122
                           float[] projection, float inflate, float halfW, float halfH, float halfZ, int variant )
123 a0397f32 Leszek Koltunski
    {
124 809dcae3 Leszek Koltunski
    ((EffectQueueMatrix  )queues[0]).send(width, height, distance, mipmap, projection, halfW, halfH, halfZ, variant);
125 a0397f32 Leszek Koltunski
    ((EffectQueueVertex  )queues[1]).send(inflate, variant);
126
    ((EffectQueueFragment)queues[2]).send(variant);
127
    }
128
129
///////////////////////////////////////////////////////////////////////////////////////////////////
130
131 809dcae3 Leszek Koltunski
  public static float[] getMVP(EffectQueue[] queues)
132 a0397f32 Leszek Koltunski
    {
133 d5b709df Leszek Koltunski
    return ((EffectQueueMatrix)queues[0]).getMVP();
134 a0397f32 Leszek Koltunski
    }
135
136
///////////////////////////////////////////////////////////////////////////////////////////////////
137
138 809dcae3 Leszek Koltunski
  public static void getUniforms(int programH, int variant)
139 a0397f32 Leszek Koltunski
    {
140 809dcae3 Leszek Koltunski
    EffectQueueFragment.uniforms(programH,variant);
141
    EffectQueueVertex  .uniforms(programH,variant);
142
    EffectQueueMatrix  .uniforms(programH,variant);
143 a0397f32 Leszek Koltunski
    }
144
145 26a4e5f6 leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
146 9455da17 Leszek Koltunski
// Every effect queue has an ID, which should be the same iff two queues hold the same effects.
147
// (this is a speedup: then both queues can be applied once, which seriously speeds up stuff -
148
// especially important in case of postprocessing)
149 26a4e5f6 leszek
150 d5b709df Leszek Koltunski
  private void regenerateID()
151 26a4e5f6 leszek
    {
152 3417ab4e leszek
    if( mNumEffects>0 )
153
      {
154
      ArrayList<Long> list = new ArrayList<>();
155
      for (int i = 0; i < mNumEffects; i++) list.add(mEffects[i].getID());
156
      Long id = mMapID.get(list);
157
158
      if( id!=null )
159
        {
160
        mID = id;
161
        }
162
      else
163
        {
164
        mMapID.put(list,mNextID);
165
        mID = mNextID++;
166
        }
167
      }
168
    else
169
      {
170
      mID = 0;
171
      }
172 c43abe6c Leszek Koltunski
    }
173
174 6a06a912 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
175
176 809dcae3 Leszek Koltunski
  public long getID()
177 26a4e5f6 leszek
    {
178
    return mID;
179
    }
180
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182 71887484 Leszek Koltunski
183 809dcae3 Leszek Koltunski
  public static boolean setMax(int index, int m)
184 71887484 Leszek Koltunski
    {
185 7602a827 Leszek Koltunski
    if( !DistortedLibrary.isInitialized() || m<=mMax[index] )
186 71887484 Leszek Koltunski
      {
187 26a4e5f6 leszek
      mMax[index] = m<0 ? 0:m;
188 71887484 Leszek Koltunski
      return true;
189
      }
190
191
    return false;
192
    }
193
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195
196 809dcae3 Leszek Koltunski
  public static int getMax(int index)
197 71887484 Leszek Koltunski
    {
198
    return mMax[index];
199
    }
200
201 6a06a912 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
202
203 809dcae3 Leszek Koltunski
  public static void onDestroy()
204 6a06a912 Leszek Koltunski
    {
205 3417ab4e leszek
    mNextID = 1;
206
    mMapID.clear();
207 da9b3f07 Leszek Koltunski
    EffectType.reset(mMax);
208 6a06a912 Leszek Koltunski
    }
209
210
///////////////////////////////////////////////////////////////////////////////////////////////////
211 26a4e5f6 leszek
// this assumes 0<=effect<mNumEffects
212 6a06a912 Leszek Koltunski
213 26a4e5f6 leszek
  protected void remove(int effect)
214 6bb59aad Leszek Koltunski
    {
215 26a4e5f6 leszek
    mNumEffects--;
216
217
    for(int j=effect; j<mNumEffects; j++ )
218
      {
219
      mEffects[j]         = mEffects[j+1];
220
      mCurrentDuration[j] = mCurrentDuration[j+1];
221
      mName[j]            = mName[j+1];
222
      }
223
224
    mEffects[mNumEffects] = null;
225
    }
226 6bb59aad Leszek Koltunski
227 26a4e5f6 leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
228
229 809dcae3 Leszek Koltunski
  public synchronized int removeByName(EffectName name)
230 26a4e5f6 leszek
    {
231 6b0b4f60 leszek
    int ret = 0;
232
233 6bb59aad Leszek Koltunski
    for(int i=0; i<mNumEffects; i++)
234
      {
235
      if( mEffects[i].getName() == name )
236
        {
237 1418a5eb Leszek Koltunski
        mJobs.add(new Job(DETACH,0,true,mEffects[i]));
238 6b0b4f60 leszek
        ret++;
239 6bb59aad Leszek Koltunski
        }
240
      }
241
242 6b0b4f60 leszek
    if( ret>0 )
243
      {
244 7602a827 Leszek Koltunski
      InternalMaster.newSlave(this);
245 6b0b4f60 leszek
      mNumEffectsToBe-=ret;
246
      }
247
248
    return ret;
249 6bb59aad Leszek Koltunski
    }
250
251 2ef5dd9e leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
252
253 809dcae3 Leszek Koltunski
  public synchronized int removeById(long id)
254 2ef5dd9e leszek
    {
255
    for(int i=0; i<mNumEffects; i++)
256
      {
257
      if( mEffects[i].getID() == id )
258
        {
259 1418a5eb Leszek Koltunski
        mJobs.add(new Job(DETACH,0,true,mEffects[i]));
260 7602a827 Leszek Koltunski
        InternalMaster.newSlave(this);
261 26a4e5f6 leszek
        mNumEffectsToBe--;
262
        return 1;
263 2ef5dd9e leszek
        }
264
      }
265
266 26a4e5f6 leszek
    return 0;
267 2ef5dd9e leszek
    }
268
269 6bb59aad Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
270
271 809dcae3 Leszek Koltunski
  public synchronized int removeEffect(Effect effect)
272 6a06a912 Leszek Koltunski
    {
273
    for(int i=0; i<mNumEffects; i++)
274
      {
275 15aa7d94 Leszek Koltunski
      if( mEffects[i]==effect )
276 6a06a912 Leszek Koltunski
        {
277 1418a5eb Leszek Koltunski
        mJobs.add(new Job(DETACH,0,true,mEffects[i]));
278 7602a827 Leszek Koltunski
        InternalMaster.newSlave(this);
279 26a4e5f6 leszek
        mNumEffectsToBe--;
280
        return 1;
281 6a06a912 Leszek Koltunski
        }
282
      }
283
   
284 26a4e5f6 leszek
    return 0;
285 6a06a912 Leszek Koltunski
    }
286
287
///////////////////////////////////////////////////////////////////////////////////////////////////
288 0df17fad Leszek Koltunski
// we do want to notify Listeners if they called 'abortAll' themselves but don't want to notify
289
// them if it is the library itself which is releasing resources.
290
291 809dcae3 Leszek Koltunski
  public synchronized int abortAll(boolean notify)
292 6a06a912 Leszek Koltunski
    {
293 1418a5eb Leszek Koltunski
    mJobs.add(new Job(DETALL,0,notify,null));
294 7602a827 Leszek Koltunski
    InternalMaster.newSlave(this);
295 26a4e5f6 leszek
    mNumEffectsToBe = 0;
296
    return mNumEffects;
297
    }
298 d07f2950 Leszek Koltunski
299 26a4e5f6 leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
300
  
301 809dcae3 Leszek Koltunski
  public boolean add(Effect effect)
302 26a4e5f6 leszek
    {
303 06dbccad Leszek Koltunski
    if( mMax[mIndex]>mNumEffectsToBe || !mCreated )
304 6a06a912 Leszek Koltunski
      {
305 34e43b0a Leszek Koltunski
      mJobs.add(new Job(ATTACH,-1,false,effect));
306
      InternalMaster.newSlave(this);
307
      mNumEffectsToBe++;
308
      return true;
309
      }
310
311
    return false;
312
    }
313
314
///////////////////////////////////////////////////////////////////////////////////////////////////
315
316
  public boolean add(Effect effect, int position)
317
    {
318
    if( mMax[mIndex]>mNumEffectsToBe || !mCreated )
319
      {
320
      mJobs.add(new Job(ATTACH,position,false,effect));
321 7602a827 Leszek Koltunski
      InternalMaster.newSlave(this);
322 26a4e5f6 leszek
      mNumEffectsToBe++;
323
      return true;
324 d07f2950 Leszek Koltunski
      }
325
326 26a4e5f6 leszek
    return false;
327 6a06a912 Leszek Koltunski
    }
328
329 106ae28d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
330
331
  public int getNumEffects()
332
    {
333
    return mNumEffects;
334
    }
335
336 9dacabea Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
337
338
  public Effect getEffect(int position)
339
    {
340
    if( position>=0 && position< mNumEffects )
341
      {
342
      return mEffects[position];
343
      }
344
    else
345
      {
346
      android.util.Log.e("queue", "getEffect: out of range "+position);
347
      return null;
348
      }
349
    }
350
351 6a06a912 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
352 809dcae3 Leszek Koltunski
353 26a4e5f6 leszek
  public void doWork()
354 6a06a912 Leszek Koltunski
    {
355 11845a9e Leszek Koltunski
    boolean changed = false;
356 26a4e5f6 leszek
    int num = mJobs.size();
357
    Job job;
358 15aa7d94 Leszek Koltunski
359 26a4e5f6 leszek
    for(int i=0; i<num; i++)
360 6a06a912 Leszek Koltunski
      {
361 26a4e5f6 leszek
      job = mJobs.remove(0);
362 15aa7d94 Leszek Koltunski
363 26a4e5f6 leszek
      switch(job.type)
364
        {
365 1418a5eb Leszek Koltunski
        case CREATE: int max = mMax[mIndex];
366
                     if( max>0 )
367
                       {
368
                       mUniforms        = new float[max*job.num];
369
                       mCurrentDuration = new long[max];
370
                       mEffects         = new Effect[max];
371
                       mName            = new int[max];
372
                       }
373 06dbccad Leszek Koltunski
                     mCreated = true;
374
375 1418a5eb Leszek Koltunski
                     break;
376
        case ATTACH: if( mMax[mIndex]>mNumEffects ) // it is possible that we have first
377
                       {                            // added effects and then lowered mMax
378 34e43b0a Leszek Koltunski
                       int position = job.num;
379
380
                       if( position==-1 )
381
                         {
382
                         mCurrentDuration[mNumEffects] = 0;
383
                         mEffects[mNumEffects] = job.effect;
384
                         mName[mNumEffects] = job.effect.getName().ordinal();
385 106ae28d Leszek Koltunski
386
                         mNumEffects++;
387
                         changed = true;
388 34e43b0a Leszek Koltunski
                         }
389
                       else if( position>=0 && position<=mNumEffects )
390
                         {
391
                         for(int j=mNumEffects; j>position; j--)
392
                           {
393
                           mCurrentDuration[j] = mCurrentDuration[j-1];
394
                           mEffects[j]         = mEffects[j-1];
395
                           mName[j]            = mName[j-1];
396
                           }
397
398
                         mCurrentDuration[position] = 0;
399
                         mEffects[position] = job.effect;
400
                         mName[position] = job.effect.getName().ordinal();
401
402 106ae28d Leszek Koltunski
                         mNumEffects++;
403
                         changed = true;
404
                         }
405 1418a5eb Leszek Koltunski
                       }
406
                     else
407
                       {
408
                       android.util.Log.e("queue", "failed to add effect "+job.effect.getName());
409
                       }
410 26a4e5f6 leszek
                     break;
411 1418a5eb Leszek Koltunski
        case DETACH: for(int j=0; j<mNumEffects; j++)
412 6b0b4f60 leszek
                       {
413
                       if (mEffects[j] == job.effect)
414
                         {
415
                         remove(j);
416 11845a9e Leszek Koltunski
                         changed = true;
417 6b0b4f60 leszek
                         break;
418
                         }
419
                       }
420 26a4e5f6 leszek
                     break;
421
        case DETALL: for(int j=0; j<mNumEffects; j++ )
422
                       {
423 11845a9e Leszek Koltunski
                       changed = true;
424 26a4e5f6 leszek
                       mEffects[j] = null;
425
                       }
426
427
                     mNumEffects= 0;
428
                     break;
429
        }
430 6a06a912 Leszek Koltunski
      }
431 d425545a Leszek Koltunski
432 d5b709df Leszek Koltunski
    if( changed && mIndex==EffectType.POSTPROCESS.ordinal() ) regenerateID();
433 6a06a912 Leszek Koltunski
    }
434
  }