1/*
2 * Copyright (c) 2005, 2013, 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#include <jni.h>
27#include <jlong.h>
28#include <jni_util.h>
29#include "sun_java2d_pipe_BufferedRenderPipe.h"
30#include "sun_java2d_pipe_BufferedOpCodes.h"
31#include "SpanIterator.h"
32#include "Trace.h"
33
34/* The "header" consists of a jint opcode and a jint span count value */
35#define INTS_PER_HEADER 2
36#define BYTES_PER_HEADER 8
37
38#define BYTES_PER_SPAN sun_java2d_pipe_BufferedRenderPipe_BYTES_PER_SPAN
39
40JNIEXPORT jint JNICALL
41Java_sun_java2d_pipe_BufferedRenderPipe_fillSpans
42 (JNIEnv *env, jobject pipe,
43 jobject rq, jlong buf,
44 jint bpos, jint limit,
45 jobject si, jlong pIterator,
46 jint transx, jint transy)
47{
48 SpanIteratorFuncs *pFuncs = (SpanIteratorFuncs *)jlong_to_ptr(pIterator);
49 void *srData;
50 jint spanbox[4];
51 jint spanCount = 0;
52 jint remainingBytes, remainingSpans;
53 unsigned char *bbuf;
54 jint *ibuf;
55 jint ipos;
56 jboolean hasException;
57
58 J2dTraceLn2(J2D_TRACE_INFO,
59 "BufferedRenderPipe_fillSpans: bpos=%d limit=%d",
60 bpos, limit);
61
62 if (JNU_IsNull(env, rq)) {
63 J2dRlsTraceLn(J2D_TRACE_ERROR,
64 "BufferedRenderPipe_fillSpans: rq is null");
65 return bpos;
66 }
67
68 if (JNU_IsNull(env, si)) {
69 J2dRlsTraceLn(J2D_TRACE_ERROR,
70 "BufferedRenderPipe_fillSpans: span iterator is null");
71 return bpos;
72 }
73
74 if (pFuncs == NULL) {
75 J2dRlsTraceLn(J2D_TRACE_ERROR,
76 "BufferedRenderPipe_fillSpans: native iterator not supplied");
77 return bpos;
78 }
79
80 bbuf = (unsigned char *)jlong_to_ptr(buf);
81 if (bbuf == NULL) {
82 J2dRlsTraceLn(J2D_TRACE_ERROR,
83 "BufferedRenderPipe_fillSpans: cannot get direct buffer address");
84 return bpos;
85 }
86
87 // adjust the int pointer to the current buffer position
88 ibuf = (jint *)(bbuf + bpos);
89
90 // start new operation
91 ibuf[0] = sun_java2d_pipe_BufferedOpCodes_FILL_SPANS;
92 ibuf[1] = 0; // placeholder for the span count
93
94 // skip the opcode and span count
95 ipos = INTS_PER_HEADER;
96 bpos += BYTES_PER_HEADER; // skip the opcode and span count
97
98 remainingBytes = limit - bpos;
99 remainingSpans = remainingBytes / BYTES_PER_SPAN;
100
101 srData = (*pFuncs->open)(env, si);
102 while ((*pFuncs->nextSpan)(srData, spanbox)) {
103 if (remainingSpans == 0) {
104 // fill in span count
105 ibuf[1] = spanCount;
106
107 // flush the queue
108 JNU_CallMethodByName(env, &hasException, rq, "flushNow", "(I)V", bpos);
109 if (hasException) {
110 break;
111 }
112
113 // now start a new operation
114 ibuf = (jint *)bbuf;
115 ibuf[0] = sun_java2d_pipe_BufferedOpCodes_FILL_SPANS;
116 ibuf[1] = 0; // placeholder for the span count
117
118 // skip the opcode and span count
119 ipos = INTS_PER_HEADER;
120 bpos = BYTES_PER_HEADER;
121
122 // calculate new limits
123 remainingBytes = limit - bpos;
124 remainingSpans = remainingBytes / BYTES_PER_SPAN;
125 spanCount = 0;
126 }
127
128 // enqueue span
129 ibuf[ipos++] = spanbox[0] + transx; // x1
130 ibuf[ipos++] = spanbox[1] + transy; // y1
131 ibuf[ipos++] = spanbox[2] + transx; // x2
132 ibuf[ipos++] = spanbox[3] + transy; // y2
133
134 // update positions
135 bpos += BYTES_PER_SPAN;
136 spanCount++;
137 remainingSpans--;
138 }
139 (*pFuncs->close)(env, srData);
140
141 // fill in span count
142 ibuf[1] = spanCount;
143
144 // return the current byte position
145 return bpos;
146}
147