Project

General

Profile

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

library / src / main / java / org / distorted / library / DistortedSurface.java @ 0c303a2c

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
    mToDoMap.clear();
134
    mDoneList.clear();
135

    
136
    mToDo = true;
137
    mNextClientID = 0;
138
    }
139

    
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141

    
142
  @SuppressWarnings("unused")
143
  static void debugLists()
144
    {
145
    android.util.Log.e("Surface", "Done list:");
146

    
147
    DistortedSurface surface;
148
    int num = mDoneList.size();
149

    
150
    for(int i=0; i<num; i++)
151
      {
152
      surface = mDoneList.get(i);
153
      surface.print(i, "");
154
      }
155

    
156
    android.util.Log.e("Surface", "ToDo list:");
157

    
158
    Job job;
159
    int i=0;
160

    
161
    for(Long key: mToDoMap.keySet())
162
      {
163
      job = mToDoMap.get(key);
164
      job.surface.print(i++, job.action==JOB_CREATE ? " create":" delete");
165
      }
166
    }
167

    
168
///////////////////////////////////////////////////////////////////////////////////////////////////
169

    
170
  private void print(int i, String extra)
171
    {
172
    String str;
173

    
174
    if( this instanceof DistortedFramebuffer ) str = (i+": Framebuffer ");
175
    else if( this instanceof DistortedTexture) str = (i+": Texture     ");
176
    else if( this instanceof DistortedScreen ) str = (i+": Screen      ");
177
    else                                       str = (i+": UNKNOWN     ");
178

    
179
    str += ("("+getWidth()+","+getHeight()+") surfaceID:"+getID());
180

    
181
    switch(mType)
182
      {
183
      case TYPE_SYST: str+=" SYSTEM"; break;
184
      case TYPE_USER: str+=" USER"  ; break;
185
      case TYPE_TREE: str+=" TREE"  ; break;
186
      default       : str+=" ERROR??";
187
      }
188

    
189
    android.util.Log.e("Surface", str+extra);
190
    }
191

    
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193

    
194
  DistortedSurface(int width, int height, int create, int type)
195
    {
196
    mSizeX        = width ;
197
    mSizeY        = height;
198
    mColorCreated = create;
199
    mColorH[0]    = 0;
200
    mID           = type==TYPE_SYST ? --mNextSystemID : ++mNextClientID;
201
    mType         = type;
202

    
203
    if( create!=DONT_CREATE )
204
      {
205
      mToDoMap.put(mID, new Job(this,JOB_CREATE) );
206
      mToDo = true;
207
      }
208
    }
209

    
210
///////////////////////////////////////////////////////////////////////////////////////////////////
211

    
212
  synchronized void markForCreation()
213
    {
214
    mDoneList.remove(this);
215
    mToDoMap.put(mID, new Job(this,JOB_CREATE) );
216
    mToDo = true;
217
    }
218

    
219
///////////////////////////////////////////////////////////////////////////////////////////////////
220
// PUBLIC API
221
///////////////////////////////////////////////////////////////////////////////////////////////////
222
/**
223
 * Mark the underlying OpenGL object for deletion. Actual deletion will take place on the next render.
224
 */
225
  synchronized public void markForDeletion()
226
    {
227
    mDoneList.remove(this);
228
    mToDoMap.put(mID, new Job(this,JOB_DELETE) );
229
    mToDo = true;
230
    }
231

    
232
////////////////////////////////////////////////////////////////////////////////////////////////////
233
/**
234
 * Return unique ID of this Surface.
235
 */
236
  public long getID()
237
    {
238
    return mID;
239
    }
240

    
241
///////////////////////////////////////////////////////////////////////////////////////////////////
242

    
243
/**
244
 * Return the width of this Surface.
245
 *
246
 * @return width of the Object, in pixels.
247
 */
248
  public int getWidth()
249
    {
250
    return mSizeX;
251
    }
252

    
253
///////////////////////////////////////////////////////////////////////////////////////////////////
254
/**
255
 * Return the height of this Surface.
256
 *
257
 * @return height of the Object, in pixels.
258
 */
259
  public int getHeight()
260
    {
261
    return mSizeY;
262
    }
263

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