/*
* 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 <jni.h>
#include "jlong.h"
#include "D3DPipeline.h"
#include "SurfaceData.h"
#include "D3DBlitLoops.h"
#include "D3DRenderQueue.h"
#include "D3DSurfaceData.h"
#include "GraphicsPrimitiveMgr.h"
#include "IntArgb.h"
#include "IntArgbPre.h"
#include "IntRgb.h"
#include "IntBgr.h"
#include "Ushort555Rgb.h"
#include "Ushort565Rgb.h"
#include "ByteIndexed.h"
#ifdef D3D_PPL_DLL
{
int t;
}
{
int t;
}
{
w = (w <= 0) ? x : x+w;
if (w < x) {
w = 0x7fffffff;
}
}
}
h = (h <= 0) ? y : y+h;
if (h < y) {
h = 0x7fffffff;
}
}
}
}
{
int t;
}
#endif /* D3D_PPL_DLL */
{
" rect={%-4d, %-4d, %-4d, %-4d}",
// srcInfo.bounds.x1 = 0;
// srcInfo.bounds.y1 = 0;
case D3DFMT_A8R8G8B8:
break;
case D3DFMT_X8R8G8B8:
break;
case D3DFMT_X8B8G8R8:
break;
case D3DFMT_X1R5G5B5:
break;
case D3DFMT_R5G6B5:
break;
default:
"D3DBL_CopySurfaceToIntArgbImage: unknown format %d",
}
return pSurface->UnlockRect();
}
int srctype,
{
" srctype=%d rect={%-4d, %-4d, %-4d, %-4d}",
// it is safe to lock with discard because we don't care about the
// contents of dynamic textures, and some drivers are happier if
// dynamic textures are always locked with DISCARD
} else {
// in non-DYNAMIC case we lock the exact rect so there's no need to
// offset the destination pointer
dstx = 0;
dsty = 0;
}
// dstInfo.bounds.x1 = 0;
// dstInfo.bounds.y1 = 0;
switch (srctype) {
case ST_INT_ARGB:
break;
case ST_INT_ARGB_PRE:
break;
case ST_INT_RGB:
break;
case ST_INT_ARGB_BM:
// REMIND: we don't have such sw loop
// so this path is disabled for now on java level
// IntArgbBmToIntArgbPreConvert(pSrcBase, pDstBase,
// srcWidth, srcHeight,
// pSrcInfo, &dstInfo, NULL, NULL);
break;
case ST_INT_BGR:
break;
case ST_3BYTE_BGR:
break;
case ST_USHORT_555_RGB:
break;
case ST_USHORT_565_RGB:
break;
case ST_BYTE_INDEXED:
break;
case ST_BYTE_INDEXED_BM:
// REMIND: we don't have such sw loop
// so this path is disabled for now on java level
// ByteIndexedBmToIntArgbPreConvert(pSrcBase, pDstBase,
// srcWidth, srcHeight,
// pSrcInfo, &dstInfo, NULL, NULL);
break;
default:
"D3DBL_CopyImageToIntXrgbSurface: unknown type %d",
srctype);
}
return pDstSurface->UnlockRect();
}
/**
* Inner loop used for copying a source "render-to" D3D "Surface" to a
* destination D3D "Surface". Note that the same surface can
* not be used as both the source and destination, as is the case in a copyArea()
* operation. This method is invoked from D3DBlitLoops_IsoBlit().
*
* The standard StretchRect() mechanism is used to copy the source region
* into the destination region. If the regions have different dimensions,
* the source will be scaled into the destination as appropriate (only
* nearest neighbor filtering will be applied for simple scale operations).
*/
{
// need to clip the destination bounds,
// otherwise StretchRect could fail
}
}
}
}
}
// check if the rects are empty (StretchRect will fail if so)
{
return S_OK;
}
}
/**
* A convenience method for issuing DrawTexture calls depending on the
* hint. See detailed explanation below.
*/
static inline HRESULT
{
if (hint == D3DTEXF_LINEAR &&
{
/*
* When the image bounds are smaller than the bounds of the
* texture that the image resides in, D3DTEXF_LINEAR will use pixels
* from outside the valid image bounds, which could result in garbage
* pixels showing up at the edges of the transformed result. We set
* the texture wrap mode to D3DTADDRESS_CLAMP, which solves the problem
* for the top and left edges. But when the source bounds do not
* match the texture bounds, we need to perform this as a four-part
* operation in order to prevent the filter used by D3D from using
* invalid pixels at the bottom and right edges.
*
* Note that we only need to apply this technique when the source
* bounds are equal to the actual image bounds. If the source bounds
* fall within the image bounds there is no need to apply this hack
* because the filter used by D3D will access valid pixels.
* Likewise, if the image bounds are equal to the texture bounds,
* then the edge conditions are handled properly by D3DTADDRESS_CLAMP.
*/
// These values represent the bottom-right corner of source texture
// region pulled in by 1/2 of a source texel.
// These values represent the above coordinates pulled in by a
// tiny fraction. As an example, if we sample the tiny area from
// tx2adj2 to tx2adj, the result should be the solid color at the
// texel center corresponding to tx2adj.
// These values represent the bottom-right corner of the destination
// region pulled in by 1/2 of a destination pixel.
// First, render a majority of the source texture, from the top-left
// corner to the bottom-right, but not including the right or bottom
// edges.
// Second, render the remaining sliver on the right edge.
// Third, render the remaining sliver on the bottom edge.
// Finally, render the remaining speck at the bottom-right corner.
} else {
/*
* As mentioned above, we can issue a simple textured quad if:
* - the hint is D3DTEXF_POINT or
* - the source bounds are sufficiently inside the texture bounds or
* - the image bounds are equal to the texture bounds (as is the
* case when the image has power-of-two dimensions, or when the
* device supports non-pow2 textures)
*/
}
return res;
}
/**
* Inner loop used for copying a source D3D "Texture" to a destination
* D3D "Surface". This method is invoked from D3DBlitLoops_IsoBlit().
*
* This method will copy, scale, or transform the source texture into the
* destination depending on the transform state, as established in
* and D3DContext::SetTransform(). If the source texture is
* transformed in any way when rendered into the destination, the filtering
* method applied is determined by the hint parameter.
*/
static HRESULT
{
{
"D3DBlitTextureToSurface: BeginScene or SetTexture failed");
return res;
}
// convert the source bounds into the range [0,1]
}
/**
* Inner loop used for copying a source system memory ("Sw") surface or
* D3D "Surface" to a destination D3D "Surface", using an D3D texture
* tile as an intermediate surface. This method is invoked from
* D3DBlitLoops_Blit() for "Sw" surfaces and D3DBlitLoops_IsoBlit() for
* "Surface" surfaces.
*
* This method is used to transform the source surface into the destination.
* Pixel rectangles cannot be arbitrarily transformed. However, texture
* mapped quads do respect the modelview transform matrix, so we use
* textures here to perform the transform operation. This method uses a
* tile-based approach in which a small subregion of the source surface is
* copied into a cached texture tile. The texture tile is then mapped
* into the appropriate location in the destination surface.
*
*/
{
if (swsurface) {
} else {
}
"D3DBlitToSurfaceViaTexture: could not init blit tile");
return res;
}
tx1 = 0.0f;
ty1 = 0.0f;
if (swsurface) {
0, 0);
} else {
}
}
}
return res;
}
/**
* Inner loop used for copying a source system memory ("Sw") surface to a
* destination D3D "Texture". This method is invoked from
* D3DBlitLoops_Blit().
*
* The source surface is effectively loaded into the D3D texture object,
* which must have already been initialized by D3DSD_initTexture(). Note
* that this method is only capable of copying the source surface into the
* destination surface (i.e. no scaling or general transform is allowed).
* This restriction should not be an issue as this method is only used
* currently to cache a static system memory image into an D3D texture in
* a hidden-acceleration situation.
*/
static HRESULT
{
0, 0);
}
/**
* General blit method for copying a native D3D surface (of type "Surface"
* or "Texture") to another D3D "Surface". If texture is JNI_TRUE, this
* method will invoke the Texture->Surface inner loop; otherwise, one of the
* Surface->Surface inner loops will be invoked, depending on the transform
* state.
*/
{
"D3DBlitLoops_IsoBlit: invalid dimensions");
return E_FAIL;
}
{
}
}
}
}
if (texture) {
} else {
// StretchRect does not do compositing or clipping
} else {
// surface type is unused here
}
}
}
return res;
}
/**
* General blit method for copying a system memory ("Sw") surface to a native
* D3D surface (of type "Surface" or "Texture"). If texture is JNI_TRUE,
* this method will invoke the Sw->Texture inner loop; otherwise, one of the
* Sw->Surface inner loops will be invoked, depending on the transform state.
*/
{
"D3DBlitLoops_Blit: invalid dimensions or srctype");
return E_FAIL;
}
lockFlags |= SD_LOCK_LUT;
}
"D3DBlitLoops_Blit: could not acquire lock");
return E_FAIL;
}
{
}
}
}
}
if (texture) {
// These coordinates will always be integers since we
// only ever do a straight copy from sw to texture.
// Thus these casts are "safe" - no loss of precision.
} else {
}
}
}
return res;
}
/**
* Specialized blit method for copying a native D3D "Surface" (pbuffer,
* window, etc.) to a system memory ("Sw") surface.
*/
{
"D3DBlitLoops_SurfaceToSwBlit: dimensions are non-positive");
return S_OK;
}
"D3DBlitLoops_SurfaceToSwBlit: could not acquire dst lock");
return S_OK;
}
{
// if we read more than 50% of the image it is faster
// to get the whole thing (50% is pulled out of a hat)
if (fullRead) {
// read whole surface into a sysmem surface
// the dest surface must have the same dimensions and format as
// the source, GetBlitOSPSurface ensures that
} else {
// we first copy the source region to a temp
// render target surface of the same format as the
// source, then copy the pixels to the
// target buffered image surface
}
if (fullRead) {
} else {
&dstRect, D3DTEXF_NONE);
}
pTmpSurface, /* src surface */
&dstInfo, /* dst info */
}
}
}
}
return res;
}
{
}
}
if (!pBlitTexture || !pBlitSurface) {
"D3DBlitLoops_CopyArea: could not init blit tile");
return E_FAIL;
}
// flush the rendering first
// REMIND: see if we could always use texture mapping;
// the assumption here is that StretchRect is faster,
// if it's not, then we should always use texture mapping
// from src surface to the temp texture
if (clipType != CLIP_SHAPE) {
// just do stretch rect to the destination
// from temp surface to the destination
&dstRect,
} else {
// shape clip - have to use texture mapping
}
}
return res;
}