History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/java2d/pipe/BufferedContext.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/java2d/pipe/BufferedContext.java+470−0
@@ -0,0 +1,470 @@
1/*
2 * Copyright (c) 2005, 2008, 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
26package sun.java2d.pipe;
27
28import java.awt.AlphaComposite;
29import java.awt.Color;
30import java.awt.Composite;
31import java.awt.Paint;
32import java.awt.geom.AffineTransform;
33import sun.java2d.pipe.hw.AccelSurface;
34import sun.java2d.InvalidPipeException;
35import sun.java2d.SunGraphics2D;
36import sun.java2d.loops.XORComposite;
37import static sun.java2d.pipe.BufferedOpCodes.*;
38import static sun.java2d.pipe.BufferedRenderPipe.BYTES_PER_SPAN;
39
40/**
41 * Base context class for managing state in a single-threaded rendering
42 * environment. Each state-setting operation (e.g. SET_COLOR) is added to
43 * the provided RenderQueue, which will be processed at a later time by a
44 * single thread. Note that the RenderQueue lock must be acquired before
45 * calling the validate() method (or any other method in this class). See
46 * the RenderQueue class comments for a sample usage scenario.
47 *
48 * @see RenderQueue
49 */
50public abstract class BufferedContext {
51
52 /*
53 * The following flags help the internals of validate() determine
54 * the appropriate (meaning correct, or optimal) code path when
55 * setting up the current context. The flags can be bitwise OR'd
56 * together as needed.
57 */
58
59 /**
60 * Indicates that no flags are needed; take all default code paths.
61 */
62 public static final int NO_CONTEXT_FLAGS = (0 << 0);
63 /**
64 * Indicates that the source surface (or color value, if it is a simple
65 * rendering operation) is opaque (has an alpha value of 1.0). If this
66 * flag is present, it allows us to disable blending in certain
67 * situations in order to improve performance.
68 */
69 public static final int SRC_IS_OPAQUE = (1 << 0);
70 /**
71 * Indicates that the operation uses an alpha mask, which may determine
72 * the code path that is used when setting up the current paint state.
73 */
74 public static final int USE_MASK = (1 << 1);
75
76 protected RenderQueue rq;
77 protected RenderBuffer buf;
78
79 /**
80 * This is a reference to the most recently validated BufferedContext. If
81 * this value is null, it means that there is no current context. It is
82 * provided here so that validate() only needs to do a quick reference
83 * check to see if the BufferedContext passed to that method is the same
84 * as the one we've cached here.
85 */
86 protected static BufferedContext currentContext;
87
88 private AccelSurface validatedSrcData;
89 private AccelSurface validatedDstData;
90 private Region validatedClip;
91 private Composite validatedComp;
92 private Paint validatedPaint;
93 // renamed from isValidatedPaintAColor as part of a work around for 6764257
94 private boolean isValidatedPaintJustAColor;
95 private int validatedRGB;
96 private int validatedFlags;
97 private boolean xformInUse;
98 private int transX;
99 private int transY;
100
101 protected BufferedContext(RenderQueue rq) {
102 this.rq = rq;
103 this.buf = rq.getBuffer();
104 }
105
106 /**
107 * Fetches the BufferedContextContext associated with the dst. surface
108 * and validates the context using the given parameters. Most rendering
109 * operations will call this method first in order to set the necessary
110 * state before issuing rendering commands.
111 *
112 * Note: must be called while the RenderQueue lock is held.
113 *
114 * @throws InvalidPipeException if either src or dest surface is not valid
115 * or lost
116 * @see RenderQueue#lock
117 * @see RenderQueue#unlock
118 */
119 public static void validateContext(AccelSurface srcData,
120 AccelSurface dstData,
121 Region clip, Composite comp,
122 AffineTransform xform,
123 Paint paint, SunGraphics2D sg2d,
124 int flags)
125 {
126 // assert rq.lock.isHeldByCurrentThread();
127 BufferedContext d3dc = dstData.getContext();
128 d3dc.validate(srcData, dstData,
129 clip, comp, xform, paint, sg2d, flags);
130 }
131
132 /**
133 * Fetches the BufferedContextassociated with the surface
134 * and disables all context state settings.
135 *
136 * Note: must be called while the RenderQueue lock is held.
137 *
138 * @throws InvalidPipeException if the surface is not valid
139 * or lost
140 * @see RenderQueue#lock
141 * @see RenderQueue#unlock
142 */
143 public static void validateContext(AccelSurface surface) {
144 // assert rt.lock.isHeldByCurrentThread();
145 validateContext(surface, surface,
146 null, null, null, null, null, NO_CONTEXT_FLAGS);
147 }
148
149 /**
150 * Validates the given parameters against the current state for this
151 * context. If this context is not current, it will be made current
152 * for the given source and destination surfaces, and the viewport will
153 * be updated. Then each part of the context state (clip, composite,
154 * etc.) is checked against the previous value. If the value has changed
155 * since the last call to validate(), it will be updated accordingly.
156 *
157 * Note that the SunGraphics2D parameter is only used for the purposes
158 * of validating a (non-null) Paint parameter. In all other cases it
159 * is safe to pass a null SunGraphics2D and it will be ignored.
160 *
161 * Note: must be called while the RenderQueue lock is held.
162 *
163 * @throws InvalidPipeException if either src or dest surface is not valid
164 * or lost
165 */
166 public void validate(AccelSurface srcData, AccelSurface dstData,
167 Region clip, Composite comp,
168 AffineTransform xform,
169 Paint paint, SunGraphics2D sg2d, int flags)
170 {
171 // assert rq.lock.isHeldByCurrentThread();
172
173 boolean updateClip = false;
174 boolean updatePaint = false;
175
176 if (!dstData.isValid() ||
177 dstData.isSurfaceLost() || srcData.isSurfaceLost())
178 {
179 invalidateContext();
180 throw new InvalidPipeException("bounds changed or surface lost");
181 }
182
183 if (paint instanceof Color) {
184 // REMIND: not 30-bit friendly
185 int newRGB = ((Color)paint).getRGB();
186 if (isValidatedPaintJustAColor) {
187 if (newRGB != validatedRGB) {
188 validatedRGB = newRGB;
189 updatePaint = true;
190 }
191 } else {
192 validatedRGB = newRGB;
193 updatePaint = true;
194 isValidatedPaintJustAColor = true;
195 }
196 } else if (validatedPaint != paint) {
197 updatePaint = true;
198 // this should be set when we are switching from paint to color
199 // in which case this condition will be true
200 isValidatedPaintJustAColor = false;
201 }
202
203 if ((currentContext != this) ||
204 (srcData != validatedSrcData) ||
205 (dstData != validatedDstData))
206 {
207 if (dstData != validatedDstData) {
208 // the clip is dependent on the destination surface, so we
209 // need to update it if we have a new destination surface
210 updateClip = true;
211 }
212
213 if (paint == null) {
214 // make sure we update the color state (otherwise, it might
215 // not be updated if this is the first time the context
216 // is being validated)
217 updatePaint = true;
218 }
219
220 // update the current source and destination surfaces
221 setSurfaces(srcData, dstData);
222
223 currentContext = this;
224 validatedSrcData = srcData;
225 validatedDstData = dstData;
226 }
227
228 // validate clip
229 if ((clip != validatedClip) || updateClip) {
230 if (clip != null) {
231 if (updateClip ||
232 validatedClip == null ||
233 !(validatedClip.isRectangular() && clip.isRectangular()) ||
234 ((clip.getLoX() != validatedClip.getLoX() ||
235 clip.getLoY() != validatedClip.getLoY() ||
236 clip.getHiX() != validatedClip.getHiX() ||
237 clip.getHiY() != validatedClip.getHiY())))
238 {
239 setClip(clip);
240 }
241 } else {
242 resetClip();
243 }
244 validatedClip = clip;
245 }
246
247 // validate composite (note that a change in the context flags
248 // may require us to update the composite state, even if the
249 // composite has not changed)
250 if ((comp != validatedComp) || (flags != validatedFlags)) {
251 if (comp != null) {
252 setComposite(comp, flags);
253 } else {
254 resetComposite();
255 }
256 // the paint state is dependent on the composite state, so make
257 // sure we update the color below
258 updatePaint = true;
259 validatedComp = comp;
260 validatedFlags = flags;
261 }
262
263 // validate transform
264 boolean txChanged = false;
265 if (xform == null) {
266 if (xformInUse) {
267 resetTransform();
268 xformInUse = false;
269 txChanged = true;
270 } else if (sg2d != null) {
271 if (transX != sg2d.transX || transY != sg2d.transY) {
272 txChanged = true;
273 }
274 }
275 if (sg2d != null) {
276 transX = sg2d.transX;
277 transY = sg2d.transY;
278 }
279 } else {
280 setTransform(xform);
281 xformInUse = true;
282 txChanged = true;
283 }
284 // non-Color paints may require paint revalidation
285 if (!isValidatedPaintJustAColor && txChanged) {
286 updatePaint = true;
287 }
288
289 // validate paint
290 if (updatePaint) {
291 if (paint != null) {
292 BufferedPaints.setPaint(rq, sg2d, paint, flags);
293 } else {
294 BufferedPaints.resetPaint(rq);
295 }
296 validatedPaint = paint;
297 }
298
299 // mark dstData dirty
300 // REMIND: is this really needed now? we do it in SunGraphics2D..
301 dstData.markDirty();
302 }
303
304 /**
305 * Invalidates the surfaces associated with this context. This is
306 * useful when the context is no longer needed, and we want to break
307 * the chain caused by these surface references.
308 *
309 * Note: must be called while the RenderQueue lock is held.
310 *
311 * @see RenderQueue#lock
312 * @see RenderQueue#unlock
313 */
314 public void invalidateSurfaces() {
315 validatedSrcData = null;
316 validatedDstData = null;
317 }
318
319 private void setSurfaces(AccelSurface srcData,
320 AccelSurface dstData)
321 {
322 // assert rq.lock.isHeldByCurrentThread();
323 rq.ensureCapacityAndAlignment(20, 4);
324 buf.putInt(SET_SURFACES);
325 buf.putLong(srcData.getNativeOps());
326 buf.putLong(dstData.getNativeOps());
327 }
328
329 private void resetClip() {
330 // assert rq.lock.isHeldByCurrentThread();
331 rq.ensureCapacity(4);
332 buf.putInt(RESET_CLIP);
333 }
334
335 private void setClip(Region clip) {
336 // assert rq.lock.isHeldByCurrentThread();
337 if (clip.isRectangular()) {
338 rq.ensureCapacity(20);
339 buf.putInt(SET_RECT_CLIP);
340 buf.putInt(clip.getLoX()).putInt(clip.getLoY());
341 buf.putInt(clip.getHiX()).putInt(clip.getHiY());
342 } else {
343 rq.ensureCapacity(28); // so that we have room for at least a span
344 buf.putInt(BEGIN_SHAPE_CLIP);
345 buf.putInt(SET_SHAPE_CLIP_SPANS);
346 // include a placeholder for the span count
347 int countIndex = buf.position();
348 buf.putInt(0);
349 int spanCount = 0;
350 int remainingSpans = buf.remaining() / BYTES_PER_SPAN;
351 int span[] = new int[4];
352 SpanIterator si = clip.getSpanIterator();
353 while (si.nextSpan(span)) {
354 if (remainingSpans == 0) {
355 buf.putInt(countIndex, spanCount);
356 rq.flushNow();
357 buf.putInt(SET_SHAPE_CLIP_SPANS);
358 countIndex = buf.position();
359 buf.putInt(0);
360 spanCount = 0;
361 remainingSpans = buf.remaining() / BYTES_PER_SPAN;
362 }
363 buf.putInt(span[0]); // x1
364 buf.putInt(span[1]); // y1
365 buf.putInt(span[2]); // x2
366 buf.putInt(span[3]); // y2
367 spanCount++;
368 remainingSpans--;
369 }
370 buf.putInt(countIndex, spanCount);
371 rq.ensureCapacity(4);
372 buf.putInt(END_SHAPE_CLIP);
373 }
374 }
375
376 private void resetComposite() {
377 // assert rq.lock.isHeldByCurrentThread();
378 rq.ensureCapacity(4);
379 buf.putInt(RESET_COMPOSITE);
380 }
381
382 private void setComposite(Composite comp, int flags) {
383 // assert rq.lock.isHeldByCurrentThread();
384 if (comp instanceof AlphaComposite) {
385 AlphaComposite ac = (AlphaComposite)comp;
386 rq.ensureCapacity(16);
387 buf.putInt(SET_ALPHA_COMPOSITE);
388 buf.putInt(ac.getRule());
389 buf.putFloat(ac.getAlpha());
390 buf.putInt(flags);
391 } else if (comp instanceof XORComposite) {
392 int xorPixel = ((XORComposite)comp).getXorPixel();
393 rq.ensureCapacity(8);
394 buf.putInt(SET_XOR_COMPOSITE);
395 buf.putInt(xorPixel);
396 } else {
397 throw new InternalError("not yet implemented");
398 }
399 }
400
401 private void resetTransform() {
402 // assert rq.lock.isHeldByCurrentThread();
403 rq.ensureCapacity(4);
404 buf.putInt(RESET_TRANSFORM);
405 }
406
407 private void setTransform(AffineTransform xform) {
408 // assert rq.lock.isHeldByCurrentThread();
409 rq.ensureCapacityAndAlignment(52, 4);
410 buf.putInt(SET_TRANSFORM);
411 buf.putDouble(xform.getScaleX());
412 buf.putDouble(xform.getShearY());
413 buf.putDouble(xform.getShearX());
414 buf.putDouble(xform.getScaleY());
415 buf.putDouble(xform.getTranslateX());
416 buf.putDouble(xform.getTranslateY());
417 }
418
419 /**
420 * Resets this context's surfaces and all attributes.
421 *
422 * Note: must be called while the RenderQueue lock is held.
423 *
424 * @see RenderQueue#lock
425 * @see RenderQueue#unlock
426 */
427 public void invalidateContext() {
428 resetTransform();
429 resetComposite();
430 resetClip();
431 BufferedPaints.resetPaint(rq);
432 invalidateSurfaces();
433 validatedComp = null;
434 validatedClip = null;
435 validatedPaint = null;
436 isValidatedPaintJustAColor = false;
437 xformInUse = false;
438 }
439
440 /**
441 * Returns a singleton {@code RenderQueue} object used by the rendering
442 * pipeline.
443 *
444 * @return a render queue
445 * @see RenderQueue
446 */
447 public abstract RenderQueue getRenderQueue();
448
449 /**
450 * Saves the the state of this context.
451 * It may reset the current context.
452 *
453 * Note: must be called while the RenderQueue lock is held.
454 *
455 * @see RenderQueue#lock
456 * @see RenderQueue#unlock
457 */
458 public abstract void saveState();
459
460 /**
461 * Restores the native state of this context.
462 * It may reset the current context.
463 *
464 * Note: must be called while the RenderQueue lock is held.
465 *
466 * @see RenderQueue#lock
467 * @see RenderQueue#unlock
468 */
469 public abstract void restoreState();
470}