Bug 1087685 - Port gfxQuartzNativeDrawing to Moz2D. r=mattwoodrow

This commit is contained in:
Jonathan Watt 2014-10-24 08:26:27 +01:00
parent 80d17fc2dc
commit fda24039d1
4 changed files with 50 additions and 47 deletions

View File

@ -4,18 +4,16 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gfxQuartzNativeDrawing.h"
#include "gfxQuartzSurface.h"
#include "gfxPlatform.h"
#include "cairo-quartz.h"
#include "gfx2DGlue.h"
#include "mozilla/gfx/Helpers.h"
using namespace mozilla::gfx;
using namespace mozilla;
gfxQuartzNativeDrawing::gfxQuartzNativeDrawing(gfxContext* ctx,
const gfxRect& nativeRect)
: mContext(ctx)
, mNativeRect(ToRect(nativeRect))
gfxQuartzNativeDrawing::gfxQuartzNativeDrawing(DrawTarget& aDrawTarget,
const Rect& nativeRect)
: mDrawTarget(&aDrawTarget)
, mNativeRect(nativeRect)
, mCGContext(nullptr)
{
}
@ -25,32 +23,32 @@ gfxQuartzNativeDrawing::BeginNativeDrawing()
{
NS_ASSERTION(!mCGContext, "BeginNativeDrawing called when drawing already in progress");
DrawTarget *dt = mContext->GetDrawTarget();
DrawTarget *dt = mDrawTarget;
if (dt->GetBackendType() != BackendType::COREGRAPHICS ||
dt->IsDualDrawTarget() ||
dt->IsTiledDrawTarget()) {
// We need a DrawTarget that we can get a CGContextRef from:
Matrix transform = dt->GetTransform();
mNativeRect = transform.TransformBounds(mNativeRect);
mNativeRect.RoundOut();
// Quartz theme drawing often adjusts drawing rects, so make
// sure our surface is big enough for that.
mNativeRect.Inflate(5);
if (mNativeRect.IsEmpty()) {
return nullptr;
}
mDrawTarget = Factory::CreateDrawTarget(BackendType::COREGRAPHICS,
IntSize(mNativeRect.width, mNativeRect.height),
SurfaceFormat::B8G8R8A8);
mTempDrawTarget =
Factory::CreateDrawTarget(BackendType::COREGRAPHICS,
IntSize(mNativeRect.width, mNativeRect.height),
SurfaceFormat::B8G8R8A8);
transform.PostTranslate(-mNativeRect.x, -mNativeRect.y);
mTempDrawTarget->SetTransform(transform);
mDrawTarget->SetTransform(transform);
dt = mDrawTarget;
dt = mTempDrawTarget;
}
mCGContext = mBorrowedContext.Init(dt);
MOZ_ASSERT(mCGContext);
return mCGContext;
@ -62,18 +60,12 @@ gfxQuartzNativeDrawing::EndNativeDrawing()
NS_ASSERTION(mCGContext, "EndNativeDrawing called without BeginNativeDrawing");
mBorrowedContext.Finish();
if (mDrawTarget) {
DrawTarget *dest = mContext->GetDrawTarget();
RefPtr<SourceSurface> source = mDrawTarget->Snapshot();
if (mTempDrawTarget) {
RefPtr<SourceSurface> source = mTempDrawTarget->Snapshot();
Matrix oldTransform = dest->GetTransform();
dest->SetTransform(Matrix());
dest->DrawSurface(source,
mNativeRect,
gfx::Rect(0, 0, mNativeRect.width, mNativeRect.height));
dest->SetTransform(oldTransform);
AutoRestoreTransform autoRestore(mDrawTarget);
mDrawTarget->SetTransform(Matrix());
mDrawTarget->DrawSurface(source, mNativeRect,
Rect(0, 0, mNativeRect.width, mNativeRect.height));
}
}

View File

@ -8,12 +8,13 @@
#include "mozilla/Attributes.h"
#include "gfxContext.h"
#include "gfxQuartzSurface.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/BorrowedContext.h"
#include "nsAutoPtr.h"
#include "mozilla/RefPtr.h"
class gfxQuartzNativeDrawing {
typedef mozilla::gfx::DrawTarget DrawTarget;
typedef mozilla::gfx::Rect Rect;
public:
/* Create native Quartz drawing for a rectangle bounded by
@ -33,16 +34,16 @@ public:
* aNativeRect is the size of the surface (in Quartz/Cocoa points) that
* will be created _if_ the gfxQuartzNativeDrawing decides to create a new
* surface and CGContext for its drawing operations, which it then
* composites into the target gfxContext.
* composites into the target DrawTarget.
*
* (Note that aNativeRect will be ignored if the gfxQuartzNativeDrawing
* uses the target gfxContext directly.)
* uses the target DrawTarget directly.)
*
* The optional aBackingScale parameter is a scaling factor that will be
* applied when creating and rendering into such a temporary surface.
*/
gfxQuartzNativeDrawing(gfxContext *ctx,
const gfxRect& aNativeRect);
gfxQuartzNativeDrawing(DrawTarget& aDrawTarget,
const Rect& aNativeRect);
/* Returns a CGContextRef which may be used for native drawing. This
* CGContextRef is valid until EndNativeDrawing is called; if it is used
@ -58,8 +59,8 @@ private:
const gfxQuartzNativeDrawing& operator=(const gfxQuartzNativeDrawing&) MOZ_DELETE;
// Final destination context
nsRefPtr<gfxContext> mContext;
mozilla::RefPtr<mozilla::gfx::DrawTarget> mDrawTarget;
mozilla::RefPtr<DrawTarget> mDrawTarget;
mozilla::RefPtr<DrawTarget> mTempDrawTarget;
mozilla::gfx::BorrowedCGContext mBorrowedContext;
mozilla::gfx::Rect mNativeRect;

View File

@ -10,6 +10,7 @@
#include "gfx2DGlue.h"
#include "gfxMatrix.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/BasicEvents.h"
#ifdef XP_WIN
// This is needed for DoublePassRenderingEvent.
@ -1252,6 +1253,8 @@ nsPluginFrame::PrintPlugin(nsRenderingContext& aRenderingContext,
// platform specific printing code
#if defined(XP_MACOSX) && !defined(__LP64__)
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
DrawTarget& aDrawTarget = *aRenderingContext.GetDrawTarget();
// Don't use this code if any of the QuickDraw APIs it currently requires
// are missing (as they probably will be on OS X 10.8 and up).
if (!&::SetRect || !&::NewGWorldFromPtr || !&::DisposeGWorld) {
@ -1272,12 +1275,12 @@ nsPluginFrame::PrintPlugin(nsRenderingContext& aRenderingContext,
ctx->NewPath();
gfxRect rect(window.x, window.y, window.width, window.height);
gfx::Rect rect(window.x, window.y, window.width, window.height);
ctx->Rectangle(rect);
ctx->Rectangle(ThebesRect(rect));
ctx->Clip();
gfxQuartzNativeDrawing nativeDraw(ctx, rect);
gfxQuartzNativeDrawing nativeDraw(aDrawTarget, rect);
CGContextRef cgContext = nativeDraw.BeginNativeDrawing();
if (!cgContext) {
nativeDraw.EndNativeDrawing();
@ -1598,6 +1601,10 @@ nsPluginFrame::PaintPlugin(nsDisplayListBuilder* aBuilder,
nsRenderingContext& aRenderingContext,
const nsRect& aDirtyRect, const nsRect& aPluginRect)
{
#if defined(XP_MACOSX)
DrawTarget& aDrawTarget = *aRenderingContext.GetDrawTarget();
#endif
#if defined(MOZ_WIDGET_ANDROID)
if (mInstanceOwner) {
gfxRect frameGfxRect =
@ -1644,7 +1651,8 @@ nsPluginFrame::PaintPlugin(nsDisplayListBuilder* aBuilder,
ctx->SetMatrix(
ctx->CurrentMatrix().Translate(offset));
gfxQuartzNativeDrawing nativeDrawing(ctx, nativeClipRect - offset);
gfxQuartzNativeDrawing nativeDrawing(aDrawTarget,
ToRect(nativeClipRect - offset));
CGContextRef cgContext = nativeDrawing.BeginNativeDrawing();
if (!cgContext) {

View File

@ -5,7 +5,9 @@
#include "nsNativeThemeCocoa.h"
#include "mozilla/gfx/2D.h"
#include "nsDeviceContext.h"
#include "nsLayoutUtils.h"
#include "nsObjCExceptions.h"
#include "nsNumberControlFrame.h"
#include "nsRangeFrame.h"
@ -2257,14 +2259,14 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
DrawTarget& aDrawTarget = *aContext->GetDrawTarget();
// setup to draw into the correct port
int32_t p2a = aFrame->PresContext()->AppUnitsPerDevPixel();
gfxRect nativeDirtyRect(aDirtyRect.x, aDirtyRect.y,
aDirtyRect.width, aDirtyRect.height);
gfx::Rect nativeDirtyRect = NSRectToRect(aDirtyRect, p2a);
gfxRect nativeWidgetRect(aRect.x, aRect.y, aRect.width, aRect.height);
nativeWidgetRect.ScaleInverse(gfxFloat(p2a));
nativeDirtyRect.ScaleInverse(gfxFloat(p2a));
nativeWidgetRect.Round();
if (nativeWidgetRect.IsEmpty())
return NS_OK; // Don't attempt to draw invisible widgets.
@ -2278,13 +2280,13 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
bool hidpi = IsHiDPIContext(aFrame->PresContext());
if (hidpi) {
// Use high-resolution drawing.
nativeWidgetRect.ScaleInverse(2.0f);
nativeDirtyRect.ScaleInverse(2.0f);
nativeWidgetRect.Scale(0.5f);
nativeDirtyRect.Scale(0.5f);
thebesCtx->SetMatrix(
thebesCtx->CurrentMatrix().Scale(2.0f, 2.0f));
}
gfxQuartzNativeDrawing nativeDrawing(thebesCtx, nativeDirtyRect);
gfxQuartzNativeDrawing nativeDrawing(aDrawTarget, nativeDirtyRect);
CGContextRef cgContext = nativeDrawing.BeginNativeDrawing();
if (cgContext == nullptr) {