/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include "D3DPipeline.h"
#include "D3DVertexCacher.h"
#include "D3DPaints.h"
#include "math.h"
// non-texturized macros
do { \
vertices[firstUnusedVertex].x = (X); \
vertices[firstUnusedVertex].y = (Y); \
firstUnusedVertex++; \
} while (0)
do { \
} while (0)
do { \
ADD_VERTEX_XYC(X, Y, VCOLOR); \
} while (0)
do { \
} while (0)
// texturized macros
do { \
vertices[firstUnusedVertex].x = (X); \
vertices[firstUnusedVertex].y = (Y); \
firstUnusedVertex++; \
} while (0)
do { \
} while (0)
do { \
} while (0)
VCOLOR) \
do { \
} while (0)
// These are fudge factors for rendering lines found by experimenting.
// They are used to tweak the geometry such that the rendering (mostly) matches
// our software rendering on most hardware. The main goal was to pick the
// numbers such that the beginning and ending pixels of lines match.
#define LINE_FUDGE
// fudge factors
#ifdef LINE_FUDGE
// For the record: value below (or larger) is required for Intel 855, but
// breaks Nvidia, ATI and Intel 965, and since the pipeline is disabled on
// 855 anyway we'll use 0.51f.
//#define HV_FF2 ( 0.5315f)
// single pixel
// diagonal, down
// For the record: with this value diagonal-down lines with Texture paint
// are a bit off on all chipsets but Intel 965. So instead we'll use
// .304f which makes it better for the rest, but at a price of a bit
//#define DD_FY2 ( 0.4f)
// diagonal, up
#else
#endif
{
*ppVC = new D3DVertexCacher();
delete *ppVC;
}
return res;
}
{
lpD3DDevice = NULL;
}
{
firstPendingBatch = 0;
firstPendingVertex = 0;
firstUnusedVertex = 0;
currentBatch = 0;
// usage depends on whether we use hw or sw vertex processing
sizeof(J2DLVERTEX));
return res;
}
void
{
}
{
// horizontal
} else {
// single point, offset a little so that a single
// pixel is rendered
}
// vertical
} else {
}
} else {
// diagonal
// ^
// \ case -> inverse
// /
// v case - inverse
} else {
// \ ^
// v or / - leave as is
}
// \
// v
} else {
// ^
// /
}
}
}
return res;
}
{
if (nPoints == 0) {
return S_OK;
}
if (isClosed &&
{
}
// npoints is exactly the number of vertices we need,
// possibly plus one (if the path is closed)
int i = 0;
do {
// leave room for one possible additional closing point
reqVerts -= vertsInBatch;
do {
i++;
vertsInBatch--;
} while (vertsInBatch > 0);
// include the last point from the current batch into the next
if (reqVerts > 0) {
i--;
reqVerts++;
// loop continues
// if this was the last batch, see if the closing point is needed;
// note that we have left the room for it
// for clarity, the loop is ended anyway
break;
// - either we went nowhere, then change the last point
// so that a single pixel is rendered
// - or it's not empty and not closed - add another
// point because on some boards the last point is not rendered
// for clarity
break;
}
}
return res;
}
{
if (scanlineCount == 0) {
return S_OK;
}
do {
reqVerts -= vertsInBatch;
do {
vertsInBatch -= 2;
} while (vertsInBatch > 0);
}
return res;
}
{
if (spanCount == 0) {
return S_OK;
}
do {
reqVerts -= vertsInBatch;
do {
vertsInBatch -= 6;
} while (vertsInBatch > 0);
}
return res;
}
{
}
// horiz: top left - top right
// horiz: bottom left - bottom right
// vert : top right - bottom right
// vert : top left - bottom left
}
return res;
}
{
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
color);
0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
color);
}
return res;
}
{
// correct texel to pixel mapping; see D3DContext::SetTransform()
// for non-id tx case
if (pCtx->IsIdentityTx()) {
fx11 -= 0.5f;
fy11 -= 0.5f;
}
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
color);
0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
color);
}
return res;
}
do { \
if ((DV) >= 0) { \
} else { \
(V) += (DV); \
} \
} while (0)
// Invert the following transform:
// DeltaT(0, 0) == (0, 0)
// DeltaT(1, 0) == (DX1, DY1)
// DeltaT(0, 1) == (DX2, DY2)
// DeltaT(1, 1) == (DX1+DX2, DY1+DY2)
// TM00 = DX1, TM01 = DX2, (TM02 = X11)
// TM10 = DY1, TM11 = DY2, (TM12 = Y11)
// Determinant = TM00*TM11 - TM01*TM10
// = DX1*DY2 - DX2*DY1
// Inverse is:
// IM02 = (TM01 * TM12 - TM11 * TM02) / det,
// IM12 = (TM10 * TM02 - TM00 * TM12) / det,
do { \
if (det == 0) { \
RET_CODE; \
} \
} while (0)
do { \
} while (0)
{
return D3D_OK);
5.0, 5.0, 6.0, 5.0, 5.0, 6.0,
color);
5.0, 6.0, 6.0, 5.0, 6.0, 6.0,
color);
}
return res;
}
{
// inner parallelogram is degenerate
// therefore it encloses no area
// fill outer
return D3D_OK);
color);
color);
}
return res;
}
{
// correct texel to pixel mapping; see D3DContext::SetTransform()
// for non-id tx case
if (pCtx->IsIdentityTx()) {
x1 -= 0.5f;
y1 -= 0.5f;
x2 -= 0.5f;
y2 -= 0.5f;
}
color);
color);
}
return res;
}
{
// correct texel to pixel mapping; see D3DContext::SetTransform()
// for non-id tx case
if (pCtx->IsIdentityTx()) {
x1 -= 0.5f;
y1 -= 0.5f;
x2 -= 0.5f;
y2 -= 0.5f;
}
color);
color);
}
return res;
}
{
// nothing to render
if (pendingVertices == 0) {
if (actionType == RESET_ACTION) {
firstPendingBatch = 0;
firstPendingVertex = 0;
firstUnusedVertex = 0;
currentBatch = 0;
}
return D3D_OK;
}
if (firstPendingVertex == 0) {
// no data in the buffer yet, we don't care about
// vertex buffer's contents
} else {
// append to the existing data in the vertex buffer
}
(void**)&lpVert, dwLockFlags)))
{
// copy only new vertices
(void *)(vertices + firstPendingVertex),
pendingVertices * sizeof(J2DLVERTEX));
"D3DVC::Render Starting flushing of %d vertices "\
"in %d batches",
switch (pType) {
// the macro for adding a line segment adds one too many prims
}
// init to something it can never be
}
} else {
}
// REMIND: may need to rethink what to do in case of an error,
// should we try to render them later?
if (actionType == RESET_ACTION) {
firstPendingBatch = 0;
firstPendingVertex = 0;
firstUnusedVertex = 0;
currentBatch = 0;
} else {
}
return res;
}
{
if (vNum > MAX_BATCH_SIZE) {
// REMIND: need to define our own errors
return D3DERR_NOTAVAILABLE;
}
// if we can't fit new vertices in the vertex buffer,
// render whatever we have in the buffer and start
// from the beginning of the vertex buffer
"D3DVC::EnsureCapacity exceeded capacity. "\
"current v: %d, requested vertices: %d\n",
return res;
}
}
"D3DVC::EnsureCapacity current batch: %d "\
" batch.type=%d newType=%d vNum=%d firstUnusedV=%d",
// there should not be multiple linestrips in a batch,
// or they will be counted as a single line strip
{
// if this is a first unused batch, use it
if (firstUnusedVertex == firstPendingVertex) {
// record the first batch and vertex scheduled for rendering
} else {
// otherwise go to the next batch
currentBatch++;
}
}
// firstUnusedVertex is updated when new vertices are added
// to the vertices array
return res;
}