jdk/src/share/classes/sun/java2d/pipe/RenderQueue.java
author henryjen
Fri, 18 Apr 2014 09:56:34 -0700
changeset 24522 3a0bbf9f5e81
parent 5506 202f599c92aa
permissions -rw-r--r--
8038644: Fix raw and unchecked warnings in sun.java2d.* Reviewed-by: darcy, prr
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     2
 * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.java2d.pipe;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.util.HashSet;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.util.Set;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import sun.awt.SunToolkit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 * The RenderQueue class encapsulates a RenderBuffer on which rendering
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 * operations are enqueued.  Note that the RenderQueue lock must be acquired
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 * before performing any operations on the queue (e.g. enqueuing an operation
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * or flushing the queue).  A sample usage scenario follows:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 *     public void drawSomething(...) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 *         rq.lock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 *         try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 *             ctx.validate(...);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 *             rq.ensureCapacity(4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 *             rq.getBuffer().putInt(DRAW_SOMETHING);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 *             ...
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 *         } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 *             rq.unlock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 *         }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 *     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * If you are enqueuing an operation that involves 8-byte parameters (i.e.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * long or double values), it is imperative that you ensure proper
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * alignment of the underlying RenderBuffer.  This can be accomplished
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * simply by providing an offset to the first 8-byte parameter in your
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * operation to the ensureCapacityAndAlignment() method.  For example:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 *     public void drawStuff(...) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 *         rq.lock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 *         try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 *             RenderBuffer buf = rq.getBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 *             ctx.validate(...);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 *             // 28 total bytes in the operation, 12 bytes to the first long
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 *             rq.ensureCapacityAndAlignment(28, 12);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 *             buf.putInt(DRAW_STUFF);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 *             buf.putInt(x).putInt(y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 *             buf.putLong(addr1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 *             buf.putLong(addr2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 *         } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 *             rq.unlock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 *         }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 *     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
public abstract class RenderQueue {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    /** The size of the underlying buffer, in bytes. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    private static final int BUFFER_SIZE = 32000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    /** The underlying buffer for this queue. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    protected RenderBuffer buf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
     * A Set containing hard references to Objects that must stay alive until
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
     * the queue has been completely flushed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
     */
24522
3a0bbf9f5e81 8038644: Fix raw and unchecked warnings in sun.java2d.*
henryjen
parents: 5506
diff changeset
    84
    protected Set<Object> refSet;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    protected RenderQueue() {
24522
3a0bbf9f5e81 8038644: Fix raw and unchecked warnings in sun.java2d.*
henryjen
parents: 5506
diff changeset
    87
        refSet = new HashSet<>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
        buf = RenderBuffer.allocate(BUFFER_SIZE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
     * Locks the queue for read/write access.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    public final void lock() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
         * Implementation note: In theory we should have two separate locks:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
         * one lock to synchronize access to the RenderQueue, and then a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
         * separate lock (the AWT lock) that only needs to be acquired when
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
         * we are about to flush the queue (using native windowing system
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
         * operations).  In practice it has been difficult to enforce the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
         * correct lock ordering; sometimes AWT will have already acquired
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
         * the AWT lock before grabbing the RQ lock (see 6253009), while the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
         * expected order should be RQ lock and then AWT lock.  Due to this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
         * issue, using two separate locks is prone to deadlocks.  Therefore,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
         * to solve this issue we have decided to eliminate the separate RQ
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
         * lock and instead just acquire the AWT lock here.  (Someday it might
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
         * be nice to go back to the old two-lock system, but that would
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
         * require potentially risky changes to AWT to ensure that it never
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
         * acquires the AWT lock before calling into 2D code that wants to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
         * acquire the RQ lock.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
        SunToolkit.awtLock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     * Attempts to lock the queue.  If successful, this method returns true,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
     * indicating that the caller is responsible for calling
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
     * <code>unlock</code>; otherwise this method returns false.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    public final boolean tryLock() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
        return SunToolkit.awtTryLock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     * Unlocks the queue.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    public final void unlock() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        SunToolkit.awtUnlock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
     * Adds the given Object to the set of hard references, which will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
     * prevent that Object from being disposed until the queue has been
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
     * flushed completely.  This is useful in cases where some enqueued
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
     * data could become invalid if the reference Object were garbage
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
     * collected before the queue could be processed.  (For example, keeping
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
     * a hard reference to a FontStrike will prevent any enqueued glyph
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
     * images associated with that strike from becoming invalid before the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     * queue is flushed.)  The reference set will be cleared immediately
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
     * after the queue is flushed each time.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    public final void addReference(Object ref) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
        refSet.add(ref);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     * Returns the encapsulated RenderBuffer object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
    public final RenderBuffer getBuffer() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        return buf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
     * Ensures that there will be enough room on the underlying buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
     * for the following operation.  If the operation will not fit given
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
     * the remaining space, the buffer will be flushed immediately, leaving
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
     * an empty buffer for the impending operation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
     * @param opsize size (in bytes) of the following operation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
    public final void ensureCapacity(int opsize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        if (buf.remaining() < opsize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
            flushNow();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
     * Convenience method that is equivalent to calling ensureCapacity()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     * followed by ensureAlignment().  The ensureCapacity() call allows for an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
     * extra 4 bytes of space in case the ensureAlignment() method needs to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
     * insert a NOOP token on the buffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
     * @param opsize size (in bytes) of the following operation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
     * @param first8ByteValueOffset offset (in bytes) from the current
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
     * position to the first 8-byte value used in the following operation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    public final void ensureCapacityAndAlignment(int opsize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
                                                 int first8ByteValueOffset)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        ensureCapacity(opsize + 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        ensureAlignment(first8ByteValueOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
     * Inserts a 4-byte NOOP token when necessary to ensure that all 8-byte
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
     * parameters for the following operation are added to the underlying
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
     * buffer with an 8-byte memory alignment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
     * @param first8ByteValueOffset offset (in bytes) from the current
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
     * position to the first 8-byte value used in the following operation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
    public final void ensureAlignment(int first8ByteValueOffset) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
        int first8ByteValuePosition = buf.position() + first8ByteValueOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        if ((first8ByteValuePosition & 7) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
            buf.putInt(BufferedOpCodes.NOOP);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
     * Immediately processes each operation currently pending on the buffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
     * This method will block until the entire buffer has been flushed.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
     * queue lock must be acquired before calling this method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
    public abstract void flushNow();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
     * Immediately processes each operation currently pending on the buffer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
     * and then invokes the provided task.  This method will block until the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
     * entire buffer has been flushed and the provided task has been executed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
     * The queue lock must be acquired before calling this method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
    public abstract void flushAndInvokeNow(Runnable task);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
     * Updates the current position of the underlying buffer, and then
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
     * flushes the queue immediately.  This method is useful when native code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
     * has added data to the queue and needs to flush immediately.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
    public void flushNow(int position) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        buf.position(position);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        flushNow();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
}