1 /* 2 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.java2d.jules; 27 28 import java.util.*; 29 30 public class TileWorker implements Runnable { 31 static final int RASTERIZED_TILE_SYNC_GRANULARITY = 8; 32 final ArrayList<JulesTile> rasterizedTileConsumerCache = 33 new ArrayList<JulesTile>(); 34 final LinkedList<JulesTile> rasterizedBuffers = new LinkedList<JulesTile>(); 35 36 IdleTileCache tileCache; 37 JulesAATileGenerator tileGenerator; 38 int workerStartIndex; 39 volatile int consumerPos = 0; 40 41 /* Threading statistics */ 42 int mainThreadCnt = 0; 43 int workerCnt = 0; 44 int doubled = 0; 45 46 public TileWorker(JulesAATileGenerator tileGenerator, int workerStartIndex, IdleTileCache tileCache) { 47 this.tileGenerator = tileGenerator; 48 this.workerStartIndex = workerStartIndex; 49 this.tileCache = tileCache; 50 } 51 52 public void run() { 53 ArrayList<JulesTile> tiles = new ArrayList<JulesTile>(16); 54 55 for (int i = workerStartIndex; i < tileGenerator.getTileCount(); i++) { 56 TileTrapContainer tile = tileGenerator.getTrapContainer(i); 57 58 if (tile != null && tile.getTileAlpha() == 127) { 59 JulesTile rasterizedTile = 60 tileGenerator.rasterizeTile(i, 61 tileCache.getIdleTileWorker( 62 tileGenerator.getTileCount() - i - 1)); 63 tiles.add(rasterizedTile); 64 65 if (tiles.size() > RASTERIZED_TILE_SYNC_GRANULARITY) { 66 addRasterizedTiles(tiles); 67 tiles.clear(); 68 } 69 } 70 71 i = Math.max(i, consumerPos + RASTERIZED_TILE_SYNC_GRANULARITY / 2); 72 } 73 addRasterizedTiles(tiles); 74 75 tileCache.disposeRasterizerResources(); 76 } 77 78 /** 79 * Returns a rasterized tile for the specified tilePos, 80 * or null if it isn't available. 81 * Allowed caller: MaskBlit/Consumer-Thread 82 */ 83 public JulesTile getPreRasterizedTile(int tilePos) { 84 JulesTile tile = null; 85 86 if (rasterizedTileConsumerCache.size() == 0 && 87 tilePos >= workerStartIndex) 88 { 89 synchronized (rasterizedBuffers) { 90 rasterizedTileConsumerCache.addAll(rasterizedBuffers); 91 rasterizedBuffers.clear(); 92 } 93 } 94 95 while (tile == null && rasterizedTileConsumerCache.size() > 0) { 96 JulesTile t = rasterizedTileConsumerCache.get(0); 97 98 if (t.getTilePos() > tilePos) { 99 break; 100 } 101 102 if (t.getTilePos() < tilePos) { 103 tileCache.releaseTile(t); 104 doubled++; 105 } 106 107 if (t.getTilePos() <= tilePos) { 108 rasterizedTileConsumerCache.remove(0); 109 } 110 111 if (t.getTilePos() == tilePos) { 112 tile = t; 113 } 114 } 115 116 if (tile == null) { 117 mainThreadCnt++; 118 119 // If there are no tiles left, tell the producer the current 120 // position. This avoids producing tiles twice. 121 consumerPos = tilePos; 122 } else { 123 workerCnt++; 124 } 125 126 return tile; 127 } 128 129 private void addRasterizedTiles(ArrayList<JulesTile> tiles) { 130 synchronized (rasterizedBuffers) { 131 rasterizedBuffers.addAll(tiles); 132 } 133 } 134 135 /** 136 * Releases cached tiles. 137 * Allowed caller: MaskBlit/Consumer-Thread 138 */ 139 public void disposeConsumerResources() { 140 synchronized (rasterizedBuffers) { 141 tileCache.releaseTiles(rasterizedBuffers); 142 } 143 144 tileCache.releaseTiles(rasterizedTileConsumerCache); 145 } 146 }