Project

General

Profile

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

library / src / main / java / org / distorted / library / DistortedSurface.java @ 05ecc6fe

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// 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
// Distorted is distributed in the hope that it will be useful,                                  //
12
// 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
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.library;
21

    
22
import java.util.HashMap;
23
import java.util.Iterator;
24
import java.util.LinkedList;
25
import java.util.Map;
26

    
27
///////////////////////////////////////////////////////////////////////////////////////////////////
28
/**
29
 * Keep all objects created in a static LinkedList. The point: we need to be able to mark
30
 * Objects for deletion, and delete all marked Objects later at a convenient time (that's
31
 * because we can only delete from a thread that holds the OpenGL context so here we provide a
32
 * framework where one is able to mark for deletion at any time and actual deletion takes place
33
 * on the next render).
34
*/
35
abstract class DistortedSurface
36
  {
37
  static final int FAILED_TO_CREATE = 1;
38
  static final int NOT_CREATED_YET  = 2;
39
  static final int DONT_CREATE      = 3;
40
  static final int CREATED          = 4;
41

    
42
  static final int TYPE_USER = 0;
43
  static final int TYPE_TREE = 1;
44
  static final int TYPE_SYST = 2;
45

    
46
  private static final int JOB_CREATE = 0;
47
  private static final int JOB_DELETE = 1;
48

    
49
  private class Job
50
    {
51
    DistortedSurface surface;
52
    int action;
53

    
54
    Job(DistortedSurface s, int a)
55
      {
56
      surface = s;
57
      action  = a;
58
      }
59
    }
60

    
61
  private static boolean mToDo = false;
62
  private static LinkedList<DistortedSurface> mDoneList = new LinkedList<>();
63
  private static HashMap<Long,Job> mToDoMap = new HashMap<>();
64
  private static long mNextClientID = 0;
65
  private static long mNextSystemID = 0;
66

    
67
  private long mID;
68
  private int mType;
69
  int mColorCreated;
70
  int[] mColorH = new int[1];
71
  int mSizeX, mSizeY;  // in screen space
72

    
73
///////////////////////////////////////////////////////////////////////////////////////////////////
74

    
75
  abstract void create();
76
  abstract void delete();
77
  abstract void recreate();
78

    
79
///////////////////////////////////////////////////////////////////////////////////////////////////
80
// must be called from a thread holding OpenGL Context
81

    
82
  static synchronized void toDo()
83
    {
84
    if( mToDo )
85
      {
86
      Job job;
87
      DistortedSurface surface;
88

    
89
      for(Long key: mToDoMap.keySet())
90
        {
91
        job = mToDoMap.get(key);
92
        surface = job.surface;
93

    
94
        //android.util.Log.d("SURFACE", "  ---> need to "+(job.action==JOB_CREATE ? "create":"delete")+" surfaceID="+surface.getID() );
95

    
96
        if( job.action==JOB_CREATE )
97
          {
98
          surface.create();
99
          mDoneList.add(surface);
100
          }
101
        else if( job.action==JOB_DELETE )
102
          {
103
          surface.delete();
104
          }
105
        }
106

    
107
      mToDoMap.clear();
108
      mToDo = false;
109
      }
110
    }
111

    
112
///////////////////////////////////////////////////////////////////////////////////////////////////
113

    
114
  static synchronized void onPause()
115
    {
116
    DistortedSurface surface;
117
    int num = mDoneList.size();
118

    
119
    for(int i=0; i<num; i++)
120
      {
121
      surface = mDoneList.removeFirst();
122
      mToDoMap.put(surface.getID(), surface.new Job(surface,JOB_CREATE) );
123
      surface.recreate();
124
      }
125

    
126
    mToDo = true;
127
    }
128

    
129
///////////////////////////////////////////////////////////////////////////////////////////////////
130

    
131
  static synchronized void onDestroy()
132
    {
133
    Job job;
134
    Iterator<Map.Entry<Long,Job>> it = mToDoMap.entrySet().iterator();
135

    
136
    while (it.hasNext())
137
      {
138
      Map.Entry<Long,Job> entry = it.next();
139
      job = entry.getValue();
140
      if (job.surface.mType!=TYPE_SYST) it.remove();
141
      }
142

    
143
    mDoneList.clear();
144

    
145
    mToDo = true;
146
    mNextClientID = 0;
147
    }
148

    
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150

    
151
  @SuppressWarnings("unused")
152
  static void debugLists()
153
    {
154
    android.util.Log.e("Surface", "Done list:");
155

    
156
    DistortedSurface surface;
157
    int num = mDoneList.size();
158

    
159
    for(int i=0; i<num; i++)
160
      {
161
      surface = mDoneList.get(i);
162
      surface.print(i, "");
163
      }
164

    
165
    android.util.Log.e("Surface", "ToDo list:");
166

    
167
    Job job;
168
    int i=0;
169

    
170
    for(Long key: mToDoMap.keySet())
171
      {
172
      job = mToDoMap.get(key);
173
      job.surface.print(i++, job.action==JOB_CREATE ? " create":" delete");
174
      }
175
    }
176

    
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178

    
179
  private void print(int i, String extra)
180
    {
181
    String str;
182

    
183
    if( this instanceof DistortedFramebuffer ) str = (i+": Framebuffer ");
184
    else if( this instanceof DistortedTexture) str = (i+": Texture     ");
185
    else if( this instanceof DistortedScreen ) str = (i+": Screen      ");
186
    else                                       str = (i+": UNKNOWN     ");
187

    
188
    str += ("("+getWidth()+","+getHeight()+") surfaceID:"+getID());
189

    
190
    switch(mType)
191
      {
192
      case TYPE_SYST: str+=" SYSTEM"; break;
193
      case TYPE_USER: str+=" USER"  ; break;
194
      case TYPE_TREE: str+=" TREE"  ; break;
195
      default       : str+=" ERROR??";
196
      }
197

    
198
    android.util.Log.e("Surface", str+extra);
199
    }
200

    
201
///////////////////////////////////////////////////////////////////////////////////////////////////
202

    
203
  DistortedSurface(int width, int height, int create, int type)
204
    {
205
    mSizeX        = width ;
206
    mSizeY        = height;
207
    mColorCreated = create;
208
    mColorH[0]    = 0;
209
    mID           = type==TYPE_SYST ? --mNextSystemID : ++mNextClientID;
210
    mType         = type;
211

    
212
    if( create!=DONT_CREATE )
213
      {
214
      mToDoMap.put(mID, new Job(this,JOB_CREATE) );
215
      mToDo = true;
216
      }
217
    }
218

    
219
///////////////////////////////////////////////////////////////////////////////////////////////////
220

    
221
  synchronized void markForCreation()
222
    {
223
    mDoneList.remove(this);
224
    mToDoMap.put(mID, new Job(this,JOB_CREATE) );
225
    mToDo = true;
226
    }
227

    
228
///////////////////////////////////////////////////////////////////////////////////////////////////
229
// PUBLIC API
230
///////////////////////////////////////////////////////////////////////////////////////////////////
231
/**
232
 * Mark the underlying OpenGL object for deletion. Actual deletion will take place on the next render.
233
 */
234
  synchronized public void markForDeletion()
235
    {
236
    mDoneList.remove(this);
237
    mToDoMap.put(mID, new Job(this,JOB_DELETE) );
238
    mToDo = true;
239
    }
240

    
241
////////////////////////////////////////////////////////////////////////////////////////////////////
242
/**
243
 * Return unique ID of this Surface.
244
 */
245
  public long getID()
246
    {
247
    return mID;
248
    }
249

    
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251

    
252
/**
253
 * Return the width of this Surface.
254
 *
255
 * @return width of the Object, in pixels.
256
 */
257
  public int getWidth()
258
    {
259
    return mSizeX;
260
    }
261

    
262
///////////////////////////////////////////////////////////////////////////////////////////////////
263
/**
264
 * Return the height of this Surface.
265
 *
266
 * @return height of the Object, in pixels.
267
 */
268
  public int getHeight()
269
    {
270
    return mSizeY;
271
    }
272

    
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274
/**
275
 * Return the depth of this Surface.
276
 * <p>
277
 * Admittedly quite a strange method. Why do we need to pass a Mesh to it? Because one cannot determine
278
 * 'depth' of a Surface (bitmap really!) when rendered based only on the texture itself, that depends
279
 * on the Mesh it is rendered with.
280
 *
281
 * @return depth of the Object, in pixels.
282
 */
283
  public int getDepth(MeshObject mesh)
284
    {
285
    return mesh==null ? 0 : (int)(mSizeX*mesh.zFactor);
286
    }
287
  }
(12-12/24)