Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/classes/sun/java2d/pipe/BufferedMaskFill.java
41159 views
1
/*
2
* Copyright (c) 2007, 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
package sun.java2d.pipe;
27
28
import java.awt.AlphaComposite;
29
import java.awt.Composite;
30
import sun.java2d.SunGraphics2D;
31
import sun.java2d.SurfaceData;
32
import sun.java2d.loops.CompositeType;
33
import sun.java2d.loops.MaskFill;
34
import sun.java2d.loops.SurfaceType;
35
import static sun.java2d.pipe.BufferedOpCodes.*;
36
37
/**
38
* The MaskFill operation is expressed as:
39
* dst = ((src <MODE> dst) * pathA) + (dst * (1 - pathA))
40
*
41
* The OGL/D3D implementation of the MaskFill operation differs from the above
42
* equation because it is not possible to perform such a complex operation in
43
* OpenGL/Direct3D (without the use of advanced techniques like fragment
44
* shaders and multitexturing). Therefore, the BufferedMaskFill operation
45
* is expressed as:
46
* dst = (src * pathA) <SrcOver> dst
47
*
48
* This simplified formula is only equivalent to the "true" MaskFill equation
49
* in the following situations:
50
* - <MODE> is SrcOver
51
* - <MODE> is Src, extra alpha == 1.0, and the source paint is opaque
52
*
53
* Therefore, we register BufferedMaskFill primitives for only the SurfaceType
54
* and CompositeType restrictions mentioned above. In addition, for the
55
* SrcNoEa case we must override the incoming composite with a SrcOver (no
56
* extra alpha) instance, so that we set up the OpenGL/Direct3D blending
57
* mode to match the BufferedMaskFill equation.
58
*/
59
public abstract class BufferedMaskFill extends MaskFill {
60
61
protected final RenderQueue rq;
62
63
protected BufferedMaskFill(RenderQueue rq,
64
SurfaceType srcType,
65
CompositeType compType,
66
SurfaceType dstType)
67
{
68
super(srcType, compType, dstType);
69
this.rq = rq;
70
}
71
72
@Override
73
public void MaskFill(SunGraphics2D sg2d, SurfaceData sData,
74
Composite comp,
75
final int x, final int y, final int w, final int h,
76
final byte[] mask,
77
final int maskoff, final int maskscan)
78
{
79
AlphaComposite acomp = (AlphaComposite)comp;
80
if (acomp.getRule() != AlphaComposite.SRC_OVER) {
81
comp = AlphaComposite.SrcOver;
82
}
83
84
rq.lock();
85
try {
86
validateContext(sg2d, comp, BufferedContext.USE_MASK);
87
88
// we adjust the mask length so that the mask ends on a
89
// 4-byte boundary
90
int maskBytesRequired;
91
if (mask != null) {
92
// we adjust the mask length so that the mask ends on a
93
// 4-byte boundary
94
maskBytesRequired = (mask.length + 3) & (~3);
95
} else {
96
// mask not needed
97
maskBytesRequired = 0;
98
}
99
int totalBytesRequired = 32 + maskBytesRequired;
100
101
RenderBuffer buf = rq.getBuffer();
102
if (totalBytesRequired <= buf.capacity()) {
103
if (totalBytesRequired > buf.remaining()) {
104
// process the queue first and then enqueue the mask
105
rq.flushNow();
106
}
107
108
buf.putInt(MASK_FILL);
109
// enqueue parameters
110
buf.putInt(x).putInt(y).putInt(w).putInt(h);
111
buf.putInt(maskoff);
112
buf.putInt(maskscan);
113
buf.putInt(maskBytesRequired);
114
if (mask != null) {
115
// enqueue the mask
116
int padding = maskBytesRequired - mask.length;
117
buf.put(mask);
118
if (padding != 0) {
119
buf.position(buf.position() + padding);
120
}
121
}
122
} else {
123
// queue is too small to accommodate entire mask; perform
124
// the operation directly on the queue flushing thread
125
rq.flushAndInvokeNow(new Runnable() {
126
public void run() {
127
maskFill(x, y, w, h,
128
maskoff, maskscan, mask.length, mask);
129
}
130
});
131
}
132
} finally {
133
rq.unlock();
134
}
135
}
136
137
/**
138
* Called as a separate Runnable when the operation is too large to fit
139
* on the RenderQueue. The OGL/D3D pipelines each have their own (small)
140
* native implementation of this method.
141
*/
142
protected abstract void maskFill(int x, int y, int w, int h,
143
int maskoff, int maskscan, int masklen,
144
byte[] mask);
145
146
/**
147
* Validates the state in the provided SunGraphics2D object and sets up
148
* any special resources for this operation (e.g. enabling gradient
149
* shading).
150
*/
151
protected abstract void validateContext(SunGraphics2D sg2d,
152
Composite comp, int ctxflags);
153
}
154
155