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/BufferedMaskBlit.java
41159 views
1
/*
2
* Copyright (c) 2007, 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.SurfaceData;
31
import sun.java2d.loops.Blit;
32
import sun.java2d.loops.CompositeType;
33
import sun.java2d.loops.MaskBlit;
34
import sun.java2d.loops.SurfaceType;
35
import static sun.java2d.pipe.BufferedOpCodes.*;
36
37
/**
38
* The MaskBlit operation is expressed as:
39
* dst = ((src <MODE> dst) * pathA) + (dst * (1 - pathA))
40
*
41
* The OGL/D3D implementation of the MaskBlit 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 BufferedMaskBlit operation
45
* is expressed as:
46
* dst = (src * pathA) <SrcOver> dst
47
*
48
* This simplified formula is only equivalent to the "true" MaskBlit equation
49
* in the following situations:
50
* - <MODE> is SrcOver
51
* - <MODE> is Src, extra alpha == 1.0, and the source surface is opaque
52
*
53
* Therefore, we register BufferedMaskBlit primitives for only the SurfaceType
54
* and CompositeType restrictions mentioned above. In addition for the Src
55
* case, we must override the composite with a SrcOver (no extra alpha)
56
* instance, so that we set up the OpenGL/Direct3D blending mode to match the
57
* BufferedMaskBlit equation.
58
*/
59
public abstract class BufferedMaskBlit extends MaskBlit {
60
61
private static final int ST_INT_ARGB = 0;
62
private static final int ST_INT_ARGB_PRE = 1;
63
private static final int ST_INT_RGB = 2;
64
private static final int ST_INT_BGR = 3;
65
66
private final RenderQueue rq;
67
private final int srcTypeVal;
68
private Blit blitop;
69
70
protected BufferedMaskBlit(RenderQueue rq,
71
SurfaceType srcType,
72
CompositeType compType,
73
SurfaceType dstType)
74
{
75
super(srcType, compType, dstType);
76
this.rq = rq;
77
if (srcType == SurfaceType.IntArgb) {
78
this.srcTypeVal = ST_INT_ARGB;
79
} else if (srcType == SurfaceType.IntArgbPre) {
80
this.srcTypeVal = ST_INT_ARGB_PRE;
81
} else if (srcType == SurfaceType.IntRgb) {
82
this.srcTypeVal = ST_INT_RGB;
83
} else if (srcType == SurfaceType.IntBgr) {
84
this.srcTypeVal = ST_INT_BGR;
85
} else {
86
throw new InternalError("unrecognized source surface type");
87
}
88
}
89
90
@Override
91
public void MaskBlit(SurfaceData src, SurfaceData dst,
92
Composite comp, Region clip,
93
int srcx, int srcy,
94
int dstx, int dsty,
95
int width, int height,
96
byte[] mask, int maskoff, int maskscan)
97
{
98
if (width <= 0 || height <= 0) {
99
return;
100
}
101
102
if (mask == null) {
103
// no mask involved; delegate to regular blit loop
104
if (blitop == null) {
105
blitop = Blit.getFromCache(src.getSurfaceType(),
106
CompositeType.AnyAlpha,
107
this.getDestType());
108
}
109
blitop.Blit(src, dst,
110
comp, clip,
111
srcx, srcy, dstx, dsty,
112
width, height);
113
return;
114
}
115
116
AlphaComposite acomp = (AlphaComposite)comp;
117
if (acomp.getRule() != AlphaComposite.SRC_OVER) {
118
comp = AlphaComposite.SrcOver;
119
}
120
121
rq.lock();
122
try {
123
validateContext(dst, comp, clip);
124
125
RenderBuffer buf = rq.getBuffer();
126
int totalBytesRequired = 20 + (width * height * 4);
127
128
/*
129
* REMIND: we should fix this so that it works with tiles that
130
* are larger than the entire buffer, but the native
131
* OGL/D3DMaskBlit isn't even prepared for tiles larger
132
* than 32x32 pixels, so there's no urgency here...
133
*/
134
rq.ensureCapacity(totalBytesRequired);
135
136
// enqueue parameters and tile pixels
137
int newpos = enqueueTile(buf.getAddress(), buf.position(),
138
src, src.getNativeOps(), srcTypeVal,
139
mask, mask.length, maskoff, maskscan,
140
srcx, srcy, dstx, dsty,
141
width, height);
142
143
buf.position(newpos);
144
} finally {
145
rq.unlock();
146
}
147
}
148
149
private native int enqueueTile(long buf, int bpos,
150
SurfaceData srcData,
151
long pSrcOps, int srcType,
152
byte[] mask, int masklen,
153
int maskoff, int maskscan,
154
int srcx, int srcy, int dstx, int dsty,
155
int width, int height);
156
157
/**
158
* Validates the context state using the given destination surface
159
* and composite/clip values.
160
*/
161
protected abstract void validateContext(SurfaceData dstData,
162
Composite comp, Region clip);
163
}
164
165