1 /* $RCSfile$
2  * $Author: hansonr $
3  * $Date: 2018-03-23 17:28:39 -0500 (Fri, 23 Mar 2018) $
4  * $Revision: 21874 $
5  *
6  * Copyright (C) 2003-2005  Miguel, Jmol Development, www.jmol.org
7  *
8  * Contact: jmol-developers@lists.sf.net
9  *
10  *  This library is free software; you can redistribute it and/or
11  *  modify it under the terms of the GNU Lesser General Public
12  *  License as published by the Free Software Foundation; either
13  *  version 2.1 of the License, or (at your option) any later version.
14  *
15  *  This library is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  *  Lesser General Public License for more details.
19  *
20  *  You should have received a copy of the GNU Lesser General Public
21  *  License along with this library; if not, write to the Free Software
22  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24 package org.jmol.g3d;
25 
26 import org.jmol.api.GenericPlatform;
27 
28 /**
29  *<p>
30  * Specifies the API to an underlying int[] buffer of ARGB values that
31  * can be converted into an Image object and a short[] for z-buffer depth.
32  *</p>
33  *
34  * @author Miguel, miguel@jmol.org
35  */
36 class Platform3D {
37 
38   int windowWidth, windowHeight, windowSize;
39   int bufferWidth, bufferHeight, bufferSize, bufferSizeT;
40 
41   Object bufferedImage;
42   int[] pBuffer, pBufferT;
43   int[] zBuffer, zBufferT;
44 
45   int widthOffscreen, heightOffscreen;
46   Object offscreenImage;
47   Object graphicsForTextOrImage;
48 
49   //final static boolean desireClearingThread = false;
50   //boolean useClearingThread = false;
51 
52   //private ClearingThread clearingThread;
53   GenericPlatform apiPlatform;
54 
Platform3D(GenericPlatform apiPlatform)55   Platform3D(GenericPlatform apiPlatform) {
56     //initialize(desireClearingThread);
57     this.apiPlatform = apiPlatform;
58   }
59 
getGraphicsForMetrics()60   Object getGraphicsForMetrics() {
61     return apiPlatform.getGraphics(allocateOffscreenImage(1, 1));
62   }
63 
64 //  final void initialize(boolean useClearingThread) {
65 //    this.useClearingThread = useClearingThread;
66 //    if (useClearingThread) {
67 //      //Logger.debug("using ClearingThread");
68 //      clearingThread = new ClearingThread();
69 //      clearingThread.start();
70 //    }
71 //  }
72 
allocateTBuffers(boolean antialiasTranslucent)73   void allocateTBuffers(boolean antialiasTranslucent) {
74     bufferSizeT = (antialiasTranslucent ? bufferSize : windowSize);
75     zBufferT = new int[bufferSizeT];
76     pBufferT = new int[bufferSizeT];
77   }
78 
79   /**
80    * @param width
81    * @param height
82    * @param antialias
83    * @param isImageWrite
84    */
allocateBuffers(int width, int height, boolean antialias, boolean isImageWrite)85   void allocateBuffers(int width, int height, boolean antialias, boolean isImageWrite) {
86     windowWidth = width;
87     windowHeight = height;
88     windowSize = width * height;
89     if (antialias) {
90       width *= 2;
91       height *= 2;
92     }
93     bufferWidth = width;
94     bufferHeight = height;
95 
96     bufferSize = bufferWidth * bufferHeight;
97     zBuffer = new int[bufferSize];
98     pBuffer = new int[bufferSize];
99     // original thought was that there is
100     // no nebed for any antialiasing on a translucent buffer
101     // but that's simply not true.
102     // bufferSizeT = windowSize;
103     bufferedImage = apiPlatform.allocateRgbImage(windowWidth, windowHeight, pBuffer, windowSize, backgroundTransparent, isImageWrite);
104   }
105 
releaseBuffers()106   void releaseBuffers() {
107     windowWidth = windowHeight = bufferWidth = bufferHeight = bufferSize = -1;
108     if (bufferedImage != null) {
109       apiPlatform.flushImage(bufferedImage);
110       bufferedImage = null;
111     }
112     pBuffer = null;
113     zBuffer = null;
114     pBufferT = null;
115     zBufferT = null;
116   }
117 
hasContent()118   boolean hasContent() {
119     for (int i = bufferSize; --i >= 0; )
120       if (zBuffer[i] != Integer.MAX_VALUE)
121         return true;
122     return false;
123   }
124 
clearScreenBuffer()125   void clearScreenBuffer() {
126     for (int i = bufferSize; --i >= 0; ) {
127       zBuffer[i] = Integer.MAX_VALUE;
128       pBuffer[i] = 0;
129     }
130   }
131 
setBackgroundColor(int bgColor)132   void setBackgroundColor(int bgColor) {
133     if (pBuffer == null)
134       return;
135     for (int i = bufferSize; --i >= 0; )
136       if (pBuffer[i] == 0)
137         pBuffer[i] = bgColor;
138   }
139 
clearTBuffer()140   void clearTBuffer() {
141     for (int i = bufferSizeT; --i >= 0; ) {
142       zBufferT[i] = Integer.MAX_VALUE;
143       pBufferT[i] = 0;
144     }
145   }
146 
clearBuffer()147   final void clearBuffer() {
148     //if (useClearingThread) {
149     //  clearingThread.clearClientBuffer();
150     //} else {
151       clearScreenBuffer();
152     //}
153   }
154 
clearScreenBufferThreaded()155   final void clearScreenBufferThreaded() {
156 //    if (useClearingThread)
157 //      clearingThread.releaseBufferForClearing();
158   }
159 
notifyEndOfRendering()160   void notifyEndOfRendering() {
161     apiPlatform.notifyEndOfRendering();
162   }
163 
getGraphicsForTextOrImage(int width, int height)164   Object getGraphicsForTextOrImage(int width, int height) {
165     if (width > widthOffscreen || height > heightOffscreen) {
166       if (offscreenImage != null) {
167         apiPlatform.disposeGraphics(graphicsForTextOrImage);
168         apiPlatform.flushImage(offscreenImage);
169       }
170       if (width > widthOffscreen)
171         widthOffscreen = width;
172       if (height > heightOffscreen)
173         heightOffscreen = height;
174       offscreenImage = allocateOffscreenImage(widthOffscreen, heightOffscreen);
175       graphicsForTextOrImage = apiPlatform.getStaticGraphics(offscreenImage, backgroundTransparent);
176     }
177     return graphicsForTextOrImage;
178   }
179 
allocateOffscreenImage(int width, int height)180   private Object allocateOffscreenImage(int width, int height) {
181     return apiPlatform.newOffScreenImage(width, height);
182   }
183 
setBackgroundTransparent(boolean tf)184   void setBackgroundTransparent(boolean tf) {
185     backgroundTransparent = tf;
186   }
187 
188 //  class ClearingThread extends Thread {
189 //
190 //
191 //    boolean bufferHasBeenCleared = false;
192 //    boolean clientHasBuffer = false;
193 //
194 //    /**
195 //     *
196 //     * @param argbBackground
197 //     */
198 //    synchronized void notifyBackgroundChange(int argbBackground) {
199 //      //Logger.debug("notifyBackgroundChange");
200 //      bufferHasBeenCleared = false;
201 //      notify();
202 //      // for now do nothing
203 //    }
204 //
205 //    synchronized void clearClientBuffer() {
206 //      //Logger.debug("obtainBufferForClient()");
207 //      while (! bufferHasBeenCleared)
208 //        try { wait(); } catch (InterruptedException ie) {}
209 //      clientHasBuffer = true;
210 //    }
211 //
212 //    synchronized void releaseBufferForClearing() {
213 //      //Logger.debug("releaseBufferForClearing()");
214 //      clientHasBuffer = false;
215 //      bufferHasBeenCleared = false;
216 //      notify();
217 //    }
218 //
219 //    synchronized void waitForClientRelease() {
220 //      //Logger.debug("waitForClientRelease()");
221 //      while (clientHasBuffer || bufferHasBeenCleared)
222 //        try { wait(); } catch (InterruptedException ie) {}
223 //    }
224 //
225 //    synchronized void notifyBufferReady() {
226 //      //Logger.debug("notifyBufferReady()");
227 //      bufferHasBeenCleared = true;
228 //      notify();
229 //    }
230 //
231 //    @Override
232 //    public void run() {
233 //      /*
234 //      Logger.debug("running clearing thread:" +
235 //                         Thread.currentThread().getPriority());
236 //      */
237 //      while (true) {
238 //        waitForClientRelease();
239 //        clearScreenBuffer();
240 //        notifyBufferReady();
241 //      }
242 //    }
243 //  }
244 
245   private static boolean backgroundTransparent = false;
246 
247 }
248