mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 892966 - Make gfxQuartzNativeDrawing support Moz2D surfaces. r=jrmuizel
This commit is contained in:
parent
6450d9080b
commit
0debdb2a99
21
gfx/2d/2D.h
21
gfx/2d/2D.h
@ -839,6 +839,8 @@ public:
|
||||
*/
|
||||
virtual void *GetNativeSurface(NativeSurfaceType aType) { return NULL; }
|
||||
|
||||
virtual bool IsDualDrawTarget() { return false; }
|
||||
|
||||
void AddUserData(UserDataKey *key, void *userData, void (*destroy)(void*)) {
|
||||
mUserData.Add(key, userData, destroy);
|
||||
}
|
||||
@ -1012,11 +1014,28 @@ private:
|
||||
class BorrowedCGContext
|
||||
{
|
||||
public:
|
||||
BorrowedCGContext(DrawTarget *aDT) : mDT(aDT)
|
||||
BorrowedCGContext()
|
||||
: cg(nullptr)
|
||||
, mDT(nullptr)
|
||||
{ }
|
||||
|
||||
BorrowedCGContext(DrawTarget *aDT)
|
||||
: mDT(aDT)
|
||||
{
|
||||
cg = BorrowCGContextFromDrawTarget(aDT);
|
||||
}
|
||||
|
||||
// We can optionally Init after construction in
|
||||
// case we don't know what the DT will be at construction
|
||||
// time.
|
||||
CGContextRef Init(DrawTarget *aDT)
|
||||
{
|
||||
MOZ_ASSERT(!mDT, "Can't initialize twice!");
|
||||
mDT = aDT;
|
||||
cg = BorrowCGContextFromDrawTarget(aDT);
|
||||
return cg;
|
||||
}
|
||||
|
||||
// The caller needs to call Finish if cg is non-null when
|
||||
// they are done with the context. This is currently explicit
|
||||
// instead of happening implicitly in the destructor to make
|
||||
|
@ -1195,6 +1195,8 @@ BorrowedCGContext::BorrowCGContextFromDrawTarget(DrawTarget *aDT)
|
||||
// save the state to make it easier for callers to avoid mucking with things
|
||||
CGContextSaveGState(cg);
|
||||
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(cgDT->mTransform));
|
||||
|
||||
return cg;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -131,6 +131,11 @@ public:
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual bool IsDualDrawTarget()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<DrawTarget> mA;
|
||||
|
@ -8,11 +8,15 @@
|
||||
#include "gfxQuartzNativeDrawing.h"
|
||||
#include "gfxQuartzSurface.h"
|
||||
#include "cairo-quartz.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
// see cairo-quartz-surface.c for the complete list of these
|
||||
enum {
|
||||
kPrivateCGCompositeSourceOver = 2
|
||||
};
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla;
|
||||
|
||||
// private Quartz routine needed here
|
||||
extern "C" {
|
||||
CG_EXTERN void CGContextSetCompositeOperation(CGContextRef, int);
|
||||
@ -21,7 +25,9 @@ extern "C" {
|
||||
gfxQuartzNativeDrawing::gfxQuartzNativeDrawing(gfxContext* ctx,
|
||||
const gfxRect& nativeRect,
|
||||
gfxFloat aBackingScale)
|
||||
: mContext(ctx), mNativeRect(nativeRect), mBackingScale(aBackingScale)
|
||||
: mContext(ctx)
|
||||
, mNativeRect(nativeRect)
|
||||
, mBackingScale(aBackingScale)
|
||||
{
|
||||
mNativeRect.RoundOut();
|
||||
}
|
||||
@ -31,6 +37,26 @@ gfxQuartzNativeDrawing::BeginNativeDrawing()
|
||||
{
|
||||
NS_ASSERTION(!mQuartzSurface, "BeginNativeDrawing called when drawing already in progress");
|
||||
|
||||
if (!mContext->IsCairo()) {
|
||||
DrawTarget *dt = mContext->GetDrawTarget();
|
||||
if (mContext->GetDrawTarget()->IsDualDrawTarget()) {
|
||||
IntSize backingSize(NSToIntFloor(mNativeRect.width * mBackingScale),
|
||||
NSToIntFloor(mNativeRect.height * mBackingScale));
|
||||
mDrawTarget = Factory::CreateDrawTarget(BACKEND_COREGRAPHICS, backingSize, FORMAT_B8G8R8A8);
|
||||
|
||||
Matrix transform;
|
||||
transform.Scale(mBackingScale, mBackingScale);
|
||||
transform.Translate(-mNativeRect.x, -mNativeRect.y);
|
||||
|
||||
mDrawTarget->SetTransform(transform);
|
||||
dt = mDrawTarget;
|
||||
}
|
||||
|
||||
mCGContext = mBorrowedContext.Init(dt);
|
||||
MOZ_ASSERT(mCGContext);
|
||||
return mCGContext;
|
||||
}
|
||||
|
||||
gfxPoint deviceOffset;
|
||||
nsRefPtr<gfxASurface> surf = mContext->CurrentSurface(&deviceOffset.x, &deviceOffset.y);
|
||||
if (!surf || surf->CairoStatus())
|
||||
@ -96,7 +122,34 @@ gfxQuartzNativeDrawing::BeginNativeDrawing()
|
||||
void
|
||||
gfxQuartzNativeDrawing::EndNativeDrawing()
|
||||
{
|
||||
NS_ASSERTION(mQuartzSurface, "EndNativeDrawing called without BeginNativeDrawing");
|
||||
NS_ASSERTION(mCGContext, "EndNativeDrawing called without BeginNativeDrawing");
|
||||
|
||||
if (mBorrowedContext.cg) {
|
||||
MOZ_ASSERT(!mContext->IsCairo());
|
||||
mBorrowedContext.Finish();
|
||||
if (mDrawTarget) {
|
||||
DrawTarget *dest = mContext->GetDrawTarget();
|
||||
RefPtr<SourceSurface> source = mDrawTarget->Snapshot();
|
||||
|
||||
IntSize backingSize(NSToIntFloor(mNativeRect.width * mBackingScale),
|
||||
NSToIntFloor(mNativeRect.height * mBackingScale));
|
||||
|
||||
Matrix oldTransform = dest->GetTransform();
|
||||
Matrix newTransform = oldTransform;
|
||||
newTransform.Translate(mNativeRect.x, mNativeRect.y);
|
||||
newTransform.Scale(1.0f / mBackingScale, 1.0f / mBackingScale);
|
||||
|
||||
dest->SetTransform(newTransform);
|
||||
|
||||
dest->DrawSurface(source,
|
||||
gfx::Rect(0, 0, backingSize.width, backingSize.height),
|
||||
gfx::Rect(0, 0, backingSize.width, backingSize.height));
|
||||
|
||||
|
||||
dest->SetTransform(oldTransform);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
cairo_quartz_finish_cg_context_with_clip(mSurfaceContext->GetCairo());
|
||||
mQuartzSurface->MarkDirty();
|
||||
|
@ -56,8 +56,11 @@ private:
|
||||
gfxQuartzNativeDrawing(const gfxQuartzNativeDrawing&) MOZ_DELETE;
|
||||
const gfxQuartzNativeDrawing& operator=(const gfxQuartzNativeDrawing&) MOZ_DELETE;
|
||||
|
||||
|
||||
// Final destination context
|
||||
nsRefPtr<gfxContext> mContext;
|
||||
mozilla::RefPtr<mozilla::gfx::DrawTarget> mDrawTarget;
|
||||
mozilla::gfx::BorrowedCGContext mBorrowedContext;
|
||||
// context that draws to mQuartzSurface; can be different from mContext
|
||||
// if mContext is not drawing to Quartz
|
||||
nsRefPtr<gfxContext> mSurfaceContext;
|
||||
|
@ -2105,7 +2105,9 @@ nsChildView::MaybeDrawResizeIndicator(GLManager* aManager, const nsIntRect& aRec
|
||||
nsIntSize size = mResizeIndicatorRect.Size();
|
||||
mResizerImage->UpdateIfNeeded(size, nsIntRegion(), ^(gfx::DrawTarget* drawTarget, const nsIntRegion& updateRegion) {
|
||||
ClearRegion(drawTarget, updateRegion);
|
||||
DrawResizer(static_cast<CGContextRef>(drawTarget->GetNativeSurface(gfx::NATIVE_SURFACE_CGCONTEXT)));
|
||||
gfx::BorrowedCGContext borrow(drawTarget);
|
||||
DrawResizer(borrow.cg);
|
||||
borrow.Finish();
|
||||
});
|
||||
|
||||
mResizerImage->Draw(aManager, mResizeIndicatorRect.TopLeft());
|
||||
@ -2165,9 +2167,8 @@ nsChildView::UpdateTitlebarImageBuffer()
|
||||
|
||||
ClearRegion(mTitlebarImageBuffer, dirtyTitlebarRegion);
|
||||
|
||||
CGContextRef ctx =
|
||||
static_cast<CGContextRef>(mTitlebarImageBuffer->GetNativeSurface(gfx::NATIVE_SURFACE_CGCONTEXT));
|
||||
CGContextSaveGState(ctx);
|
||||
gfx::BorrowedCGContext borrow(mTitlebarImageBuffer);
|
||||
CGContextRef ctx = borrow.cg;
|
||||
|
||||
double scale = BackingScaleFactor();
|
||||
CGContextScaleCTM(ctx, scale, scale);
|
||||
@ -2233,7 +2234,7 @@ nsChildView::UpdateTitlebarImageBuffer()
|
||||
DevPixelsToCocoaPoints(1));
|
||||
|
||||
[NSGraphicsContext setCurrentContext:oldContext];
|
||||
CGContextRestoreGState(ctx);
|
||||
borrow.Finish();
|
||||
|
||||
mUpdatedTitlebarRegion.Or(mUpdatedTitlebarRegion, dirtyTitlebarRegion);
|
||||
}
|
||||
@ -2290,8 +2291,9 @@ nsChildView::MaybeDrawRoundedCorners(GLManager* aManager, const nsIntRect& aRect
|
||||
nsIntSize size(mDevPixelCornerRadius, mDevPixelCornerRadius);
|
||||
mCornerMaskImage->UpdateIfNeeded(size, nsIntRegion(), ^(gfx::DrawTarget* drawTarget, const nsIntRegion& updateRegion) {
|
||||
ClearRegion(drawTarget, updateRegion);
|
||||
DrawTopLeftCornerMask(static_cast<CGContextRef>(drawTarget->GetNativeSurface(gfx::NATIVE_SURFACE_CGCONTEXT)),
|
||||
mDevPixelCornerRadius);
|
||||
gfx::BorrowedCGContext borrow(drawTarget);
|
||||
DrawTopLeftCornerMask(borrow.cg, mDevPixelCornerRadius);
|
||||
borrow.Finish();
|
||||
});
|
||||
|
||||
// Use operator destination in: multiply all 4 channels with source alpha.
|
||||
|
Loading…
Reference in New Issue
Block a user