Esempio n. 1
0
void CRenderer::Draw( IwGxPrimType type, const CIwSVec2 * vertex, const CIwSVec2 * uv, const uint16* indexStream, const CIwColour * colour, int32 vertexCount, CIwMaterial * mat )
{
	if ( mat == NULL )
	{
		mat = mDefaultMaterial;
	}
	if (( GetVBSize() + vertexCount >= RENDER_MAX_BUFF_SIZE 
		|| (mat != mCurrMtl) 
		|| (GetBufferType() != type)
		|| (uv == NULL && GetUVBSize() != 0) 
		|| (indexStream == NULL && GetIBSize() != 0)
		|| (colour == NULL && GetCBSize() != 0)
		))
	{
		DrawBatch();
	}

	if ( (uint32)vertexCount >= RENDER_MAX_BUFF_SIZE )
	{
		CIwSVec2 * _v = IW_GX_ALLOC(CIwSVec2, vertexCount);
		CIwSVec2 * _uv = IW_GX_ALLOC(CIwSVec2, vertexCount);
		CIwColour * _c = IW_GX_ALLOC(CIwColour, vertexCount);

		uint16 * _is = NULL;
		if (indexStream != NULL )
		{
			_is = IW_GX_ALLOC(uint16, vertexCount);
			memcpy(_is, indexStream, vertexCount*sizeof(uint16));
		}
		memcpy(&_v[0], &vertex[0], vertexCount*sizeof(CIwSVec2));
		memcpy(&_uv[0], &uv[0], vertexCount*sizeof(CIwSVec2));
		memcpy(&_c[0], &colour[0], vertexCount*sizeof(CIwColour));

		CameraTransform( &_v[0], vertexCount);
		DrawDirect(type, _v, _uv, _is, _c, vertexCount, mat);
	}
	else
	{
		mCurrMtl  = mat;
		SetBufferType(type);
		AddBuffer(type, vertex, uv, indexStream, colour, vertexCount);
		CameraTransform( &mVB[GetVBSize() - vertexCount], vertexCount);
	}	
}
void
gfxXlibNativeRenderer::Draw(gfxContext* ctx, nsIntSize size,
                            PRUint32 flags, Screen *screen, Visual *visual,
                            DrawOutput* result)
{
    if (result) {
        result->mSurface = NULL;
        result->mUniformAlpha = false;
        result->mUniformColor = false;
    }

    bool drawIsOpaque = (flags & DRAW_IS_OPAQUE) != 0;
    gfxMatrix matrix = ctx->CurrentMatrix();

    // We can only draw direct or onto a copied background if pixels align and
    // native drawing is compatible with the current operator.  (The matrix is
    // actually also pixel-exact for flips and right-angle rotations, which
    // would permit copying the background but not drawing direct.)
    bool matrixIsIntegerTranslation = !matrix.HasNonIntegerTranslation();
    bool canDrawOverBackground = matrixIsIntegerTranslation &&
        ctx->CurrentOperator() == gfxContext::OPERATOR_OVER;

    // The padding of 0.5 for non-pixel-exact transformations used here is
    // the same as what _cairo_pattern_analyze_filter uses.
    const gfxFloat filterRadius = 0.5;
    gfxRect affectedRect(0.0, 0.0, size.width, size.height);
    if (!matrixIsIntegerTranslation) {
        // The filter footprint means that the affected rectangle is a
        // little larger than the drawingRect;
        affectedRect.Inflate(filterRadius);

        NATIVE_DRAWING_NOTE("FALLBACK: matrix not integer translation");
    } else if (!canDrawOverBackground) {
        NATIVE_DRAWING_NOTE("FALLBACK: unsupported operator");
    }

    // Clipping to the region affected by drawing allows us to consider only
    // the portions of the clip region that will be affected by drawing.
    gfxRect clipExtents;
    {
        gfxContextAutoSaveRestore autoSR(ctx);
        ctx->Clip(affectedRect);

        clipExtents = ctx->GetClipExtents();
        if (clipExtents.IsEmpty())
            return; // nothing to do

        if (canDrawOverBackground &&
            DrawDirect(ctx, size, flags, screen, visual))
            return;
    }

    nsIntRect drawingRect(nsIntPoint(0, 0), size);
    // Drawing need only be performed within the clip extents
    // (and padding for the filter).
    if (!matrixIsIntegerTranslation) {
        // The source surface may need to be a little larger than the clip
        // extents due to the filter footprint.
        clipExtents.Inflate(filterRadius);
    }
    clipExtents.RoundOut();

    nsIntRect intExtents(PRInt32(clipExtents.X()),
                         PRInt32(clipExtents.Y()),
                         PRInt32(clipExtents.Width()),
                         PRInt32(clipExtents.Height()));
    drawingRect.IntersectRect(drawingRect, intExtents);
    gfxPoint offset(drawingRect.x, drawingRect.y);

    DrawingMethod method;
    nsRefPtr<gfxASurface> target = ctx->CurrentSurface();
    nsRefPtr<gfxXlibSurface> tempXlibSurface = 
        CreateTempXlibSurface(target, drawingRect.Size(),
                              canDrawOverBackground, flags, screen, visual,
                              &method);
    if (!tempXlibSurface)
        return;
  
    if (drawingRect.Size() != size || method == eCopyBackground) {
        // Only drawing a portion, or copying background,
        // so won't return a result.
        result = NULL;
    }

    nsRefPtr<gfxContext> tmpCtx;
    if (!drawIsOpaque) {
        tmpCtx = new gfxContext(tempXlibSurface);
        if (method == eCopyBackground) {
            tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
            tmpCtx->SetSource(target, -(offset + matrix.GetTranslation()));
            // The copy from the tempXlibSurface to the target context should
            // use operator SOURCE, but that would need a mask to bound the
            // operation.  Here we only copy opaque backgrounds so operator
            // OVER will behave like SOURCE masked by the surface.
            NS_ASSERTION(tempXlibSurface->GetContentType()
                         == gfxASurface::CONTENT_COLOR,
                         "Don't copy background with a transparent surface");
        } else {
            tmpCtx->SetOperator(gfxContext::OPERATOR_CLEAR);
        }
        tmpCtx->Paint();
    }

    if (!DrawOntoTempSurface(tempXlibSurface, -drawingRect.TopLeft())) {
        return;
    }
  
    if (method != eAlphaExtraction) {
        ctx->SetSource(tempXlibSurface, offset);
        ctx->Paint();
        if (result) {
            result->mSurface = tempXlibSurface;
            /* fill in the result with what we know, which is really just what our
               assumption was */
            result->mUniformAlpha = true;
            result->mColor.a = 1.0;
        }
        return;
    }
    
    nsRefPtr<gfxImageSurface> blackImage =
        CopyXlibSurfaceToImage(tempXlibSurface, gfxASurface::ImageFormatARGB32);
    
    tmpCtx->SetDeviceColor(gfxRGBA(1.0, 1.0, 1.0));
    tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
    tmpCtx->Paint();
    DrawOntoTempSurface(tempXlibSurface, -drawingRect.TopLeft());
    nsRefPtr<gfxImageSurface> whiteImage =
        CopyXlibSurfaceToImage(tempXlibSurface, gfxASurface::ImageFormatRGB24);
  
    if (blackImage->CairoStatus() == CAIRO_STATUS_SUCCESS &&
        whiteImage->CairoStatus() == CAIRO_STATUS_SUCCESS) {
        gfxAlphaRecovery::Analysis analysis;
        if (!gfxAlphaRecovery::RecoverAlpha(blackImage, whiteImage,
                                            result ? &analysis : nullptr))
            return;

        ctx->SetSource(blackImage, offset);

        /* if the caller wants to retrieve the rendered image, put it into
           a 'similar' surface, and use that as the source for the drawing right
           now. This means we always return a surface similar to the surface
           used for 'cr', which is ideal if it's going to be cached and reused.
           We do not return an image if the result has uniform color (including
           alpha). */
        if (result) {
            if (analysis.uniformAlpha) {
                result->mUniformAlpha = true;
                result->mColor.a = analysis.alpha;
            }
            if (analysis.uniformColor) {
                result->mUniformColor = true;
                result->mColor.r = analysis.r;
                result->mColor.g = analysis.g;
                result->mColor.b = analysis.b;
            } else {
                result->mSurface = target->
                    CreateSimilarSurface(gfxASurface::CONTENT_COLOR_ALPHA,
                                         gfxIntSize(size.width, size.height));

                gfxContext copyCtx(result->mSurface);
                copyCtx.SetSource(blackImage);
                copyCtx.SetOperator(gfxContext::OPERATOR_SOURCE);
                copyCtx.Paint();

                ctx->SetSource(result->mSurface);
            }
        }
        
        ctx->Paint();
    }
}
Esempio n. 3
0
void CTexture::Draw (string name, int x, int y, int width, int height) {
    DrawDirect (TexID (name), x, y, width, height);
}
Esempio n. 4
0
void CTexture::Draw (int idx, int x, int y, int width, int height) {
    DrawDirect (TexID (idx), x, y, width, height);
}
Esempio n. 5
0
void CTexture::Draw (string name, int x, int y, float size) {
    DrawDirect (TexID (name), x, y, size);
}
Esempio n. 6
0
void CTexture::Draw (int idx, int x, int y, float size) {
    DrawDirect (TexID (idx), x, y, size);
}
Esempio n. 7
0
void CTexture::Draw (string name) {
    DrawDirect (TexID (name));
}
Esempio n. 8
0
void CTexture::Draw (int idx) {
    DrawDirect (TexID (idx));
}