1 /*
2 * Copyright (c) 2017, 2018, 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 package sun.java2d.xr;
26
27 import java.awt.Point;
28 import java.nio.ByteBuffer;
29
30 /**
31 * Buffer for uploading AA mask tile data.
32 * Supports uploading multiple AA tiles within one buffer, by simply appending
33 * the tiles in x-direction and starting a new line once the remaining width
34 * is not sufficient anymore.
35 *
36 * @author Clemens Eisserer
37 */
38 public class AATileBuffer {
39 private final static int SHM_THRESHOLD = 8192;
40 private final static int SHM_THRESHOLD2 = 16384;
41
42 final int bufferWidth;
43 final int bufferHeight;
44 final int bufferScan;
45 final int yOffset;
46
47 final AATileBufMan bufMan;
48 final ByteBuffer buffer;
49 final int bufferId;
50 final boolean shmCapable;
51
52 int tileCount;
53 int currY;
54 int currX;
55 int currentRowHeight;
56 int maxRowWidth;
57
58 public AATileBuffer(AATileBufMan bufMan, int bufferWidth, int bufferHeight, int bufferScan, int yOffset, int bufferId, ByteBuffer buffer, boolean shmCapable) {
59 this.bufMan = bufMan;
60 this.bufferWidth = bufferWidth;
61 this.bufferHeight = bufferHeight;
62 this.bufferScan = bufferScan;
63 this.shmCapable = shmCapable;
64
65 this.yOffset = yOffset;
66 this.bufferId = bufferId;
67
68 this.buffer = buffer;
69 }
70
71 public Point storeTile(int width, int height) {
72 int dstX;
73
74 if(bufferHeight - currY - currentRowHeight < height) {
75 return null;
76 }
77
78 if(bufferHeight - currX > width) {
79 dstX = currX;
80 currX += width;
81 currentRowHeight = Math.max(currentRowHeight, height);
82 maxRowWidth = Math.max(maxRowWidth, currX);
83 } else
84 {
85 dstX = 0;
86 currX = width;
87 currY += currentRowHeight;
88 currentRowHeight = height;
89 }
90
91 tileCount++;
92
93 return new Point(dstX, currY);
94 }
95
96 public int getTileCount() {
97 return tileCount;
98 }
99
100 public void reset() {
101 currX = 0;
102 currY = 0;
103 currentRowHeight = 0;
104 maxRowWidth = 0;
105 tileCount = 0;
106 }
107
108 public Point getBufferBounds() {
109 return new Point(maxRowWidth, currY + currentRowHeight);
110 }
111
112 public Point storeMaskTile(byte[] tileData, int width, int height, int maskOff,
113 int tileScan, float ea) {
114
115 Point pt = storeTile(width, height);
116 if(pt == null) {
117 return null;
118 }
119
120 /*
121 if(ea < 0.99804687f) {
122 for(int y=0; y < height; y++) {
123 for(int x = 0; x < width; x++) {
124 tileData[]
125 }
126 }
127 } */
128
129 for(int y=0; y < height; y++) {
130 int srcPos = tileScan * y + maskOff;
131 int dstPos = bufferScan * (pt.y + y) + pt.x;
132
133 buffer.position(dstPos);
134 buffer.put(tileData, srcPos, width);
135 }
136
137 return pt;
138 }
139
140 public ByteBuffer getByteBuffer() {
141 return buffer;
142 }
143
144 public int getBufferScan() {
145 return bufferScan;
146 }
147
148 public int getYOffset() {
149 return yOffset;
150 }
151
152 public boolean isShmCapable() {
153 return shmCapable;
154 }
155
156 public boolean isUploadWithShmProfitable() {
157 int pixelsOccupied = maxRowWidth * (currY + currentRowHeight);
158
159 // in case only one shm capable buffer is left, set the treshold higher
160 // so we save the shm buffer for larger uploads later
161 return ((bufMan.getIdleShmBufferCnt() > 1 && pixelsOccupied >= SHM_THRESHOLD)
162 || pixelsOccupied >= SHM_THRESHOLD2) && shmCapable;
163 }
164
165 public int getBufferId() {
166 return bufferId;
167 }
168 }