Project

General

Profile

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

library / src / main / java / org / distorted / library / DistortedSurface.java @ c7da4e65

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.LinkedList;
23

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

    
39
  private static boolean mToDo = false;
40
  private static LinkedList<DistortedSurface> mDoneList = new LinkedList<>();
41
  private static LinkedList<DistortedSurface> mToDoList = new LinkedList<>();
42
  private static long mNextClientID = 0;
43
  private static long mNextSystemID = 0;
44

    
45
  private long mID;
46
  private boolean mMarked;
47
  private boolean mSystem;
48
  int mColorCreated;
49
  int[] mColorH = new int[1];
50
  int mSizeX, mSizeY;  // in screen space
51

    
52
///////////////////////////////////////////////////////////////////////////////////////////////////
53

    
54
  abstract void create();
55
  abstract void delete();
56
  abstract void recreate();
57

    
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59
// must be called form a thread holding OpenGL Context
60

    
61
  static synchronized void toDo()
62
    {
63
    if( mToDo )
64
      {
65
      DistortedSurface surface;
66

    
67
      int num = mToDoList.size();
68

    
69
      for(int i=0; i<num; i++)
70
        {
71
        surface = mToDoList.removeFirst();
72

    
73
        if(surface.mMarked)
74
          {
75
          surface.delete();
76
          surface.mMarked = false;
77
          }
78
        else
79
          {
80
          surface.create();
81
          mDoneList.add(surface);
82
          }
83
        }
84

    
85
      mToDo = false;
86
      }
87
    }
88

    
89
///////////////////////////////////////////////////////////////////////////////////////////////////
90

    
91
  static synchronized void onDestroy()
92
    {
93
    DistortedSurface surface;
94

    
95
    int num = mDoneList.size();
96

    
97
    for(int i=0; i<num; i++)
98
      {
99
      surface = mDoneList.removeFirst();
100

    
101
      if( surface.mSystem )
102
        {
103
        mToDoList.add(surface);
104
        surface.recreate();
105
        }
106
      }
107

    
108
    num = mToDoList.size();
109

    
110
    for(int i=0; i<num; i++)
111
      {
112
      surface = mToDoList.get(i);
113

    
114
      if( !surface.mSystem )
115
        {
116
        mDoneList.remove(i);
117
        i--;
118
        num--;
119
        }
120
      }
121

    
122
    mToDo = (num>0);
123
    mNextClientID = 0;
124
    }
125

    
126
///////////////////////////////////////////////////////////////////////////////////////////////////
127

    
128
  synchronized void moveToToDo()
129
    {
130
    if ( mDoneList.remove(this) )
131
      {
132
      mToDoList.add(this);
133
      mToDo = true;
134
      }
135
    }
136

    
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138

    
139
  @SuppressWarnings("unused")
140
  static void debugLists()
141
    {
142
    android.util.Log.e("Surface", "Done list:");
143
    debugList(mDoneList);
144
    android.util.Log.e("Surface", "ToDo list:");
145
    debugList(mToDoList);
146
    }
147

    
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149

    
150
  private static void debugList(LinkedList<DistortedSurface> list)
151
    {
152
    DistortedSurface surface;
153
    String str;
154

    
155
    int num = list.size();
156

    
157
    for(int i=0; i<num; i++)
158
      {
159
      surface = list.get(i);
160

    
161
      if( surface instanceof DistortedFramebuffer ) str = (i+": Framebuffer ");
162
      else if( surface instanceof DistortedTexture) str = (i+": Texture     ");
163
      else if( surface instanceof DistortedScreen ) str = (i+": Screen      ");
164
      else                                          str = (i+": UNKNOWN     ");
165

    
166
      str += ("("+surface.getWidth()+","+surface.getHeight()+") surfaceID:"+surface.getID());
167

    
168
      android.util.Log.e("Surface", str);
169
      }
170
    }
171

    
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173

    
174
  DistortedSurface(int width, int height, int create, boolean system)
175
    {
176
    mSizeX        = width ;
177
    mSizeY        = height;
178
    mColorCreated = create;
179
    mColorH[0]    = 0;
180
    mMarked       = false;
181
    mID           = system ? --mNextSystemID : ++mNextClientID;
182
    mSystem       = system;
183

    
184
    if( create!=DONT_CREATE )
185
      {
186
      mToDoList.add(this);
187
      mToDo = true;
188
      }
189
    }
190

    
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192
// PUBLIC API
193
///////////////////////////////////////////////////////////////////////////////////////////////////
194
/**
195
 * Mark the underlying OpenGL object for deletion. Actual deletion will take place on the next render.
196
 */
197
  public void markForDeletion()
198
    {
199
    if( !mMarked )
200
      {
201
      mToDo   = true;
202
      mMarked = true;
203
      mDoneList.remove(this);
204
      mToDoList.add(this);
205
      }
206
    }
207

    
208
////////////////////////////////////////////////////////////////////////////////////////////////////
209
/**
210
 * Return unique ID of the Surface.
211
 */
212
  public long getID()
213
    {
214
    return mID;
215
    }
216

    
217
///////////////////////////////////////////////////////////////////////////////////////////////////
218

    
219
/**
220
 * Returns the height of the Surface.
221
 *
222
 * @return height of the object, in pixels.
223
 */
224
  public int getWidth()
225
    {
226
    return mSizeX;
227
    }
228

    
229
///////////////////////////////////////////////////////////////////////////////////////////////////
230
/**
231
 * Returns the width of the Surface.
232
 *
233
 * @return width of the Object, in pixels.
234
 */
235
  public int getHeight()
236
    {
237
    return mSizeY;
238
    }
239

    
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241
/**
242
 * Returns the depth of the Surface.
243
 * <p>
244
 * Admittedly quite a strange method. Why do we need to pass a Mesh to it? Because one cannot determine
245
 * 'depth' of a Surface (bitmap really!) when rendered based only on the texture itself, that depends
246
 * on the Mesh it is rendered with.
247
 *
248
 * @return depth of the Object, in pixels.
249
 */
250
  public int getDepth(MeshObject mesh)
251
    {
252
    return mesh==null ? 0 : (int)(mSizeX*mesh.zFactor);
253
    }
254
  }
(10-10/22)