gfxQuartzSurface.cpp (2846B)
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #include "gfxQuartzSurface.h" 7 #include "gfxContext.h" 8 #include "gfxImageSurface.h" 9 #include "mozilla/gfx/2D.h" 10 #include "mozilla/gfx/HelpersCairo.h" 11 12 #include "cairo-quartz.h" 13 14 void gfxQuartzSurface::MakeInvalid() { mSize = mozilla::gfx::IntSize(-1, -1); } 15 16 gfxQuartzSurface::gfxQuartzSurface(const mozilla::gfx::IntSize& desiredSize, 17 gfxImageFormat format) 18 : mCGContext(nullptr), mSize(desiredSize) { 19 if (!mozilla::gfx::Factory::CheckSurfaceSize(desiredSize)) MakeInvalid(); 20 21 unsigned int width = static_cast<unsigned int>(mSize.width); 22 unsigned int height = static_cast<unsigned int>(mSize.height); 23 24 cairo_format_t cformat = GfxFormatToCairoFormat(format); 25 cairo_surface_t* surf = cairo_quartz_surface_create(cformat, width, height); 26 27 mCGContext = cairo_quartz_surface_get_cg_context(surf); 28 29 CGContextRetain(mCGContext); 30 31 Init(surf); 32 if (mSurfaceValid) { 33 RecordMemoryUsed(mSize.height * 4 + sizeof(gfxQuartzSurface)); 34 } 35 } 36 37 gfxQuartzSurface::gfxQuartzSurface(CGContextRef context, 38 const mozilla::gfx::IntSize& size) 39 : mCGContext(context), mSize(size) { 40 if (!mozilla::gfx::Factory::CheckSurfaceSize(size)) MakeInvalid(); 41 42 unsigned int width = static_cast<unsigned int>(mSize.width); 43 unsigned int height = static_cast<unsigned int>(mSize.height); 44 45 cairo_surface_t* surf = 46 cairo_quartz_surface_create_for_cg_context(context, width, height); 47 48 CGContextRetain(mCGContext); 49 50 Init(surf); 51 if (mSurfaceValid) { 52 RecordMemoryUsed(mSize.height * 4 + sizeof(gfxQuartzSurface)); 53 } 54 } 55 56 gfxQuartzSurface::gfxQuartzSurface(cairo_surface_t* csurf, 57 const mozilla::gfx::IntSize& aSize) 58 : mSize(aSize) { 59 mCGContext = cairo_quartz_surface_get_cg_context(csurf); 60 CGContextRetain(mCGContext); 61 62 Init(csurf, true); 63 } 64 65 already_AddRefed<gfxImageSurface> gfxQuartzSurface::GetAsImageSurface() { 66 cairo_surface_t* surface = cairo_quartz_surface_get_image(mSurface); 67 if (!surface || cairo_surface_status(surface)) return nullptr; 68 69 RefPtr<gfxASurface> img = Wrap(surface); 70 71 // cairo_quartz_surface_get_image returns a referenced image, and thebes 72 // shares the refcounts of Cairo surfaces. However, Wrap also adds a 73 // reference to the image. We need to remove one of these references 74 // explicitly so we don't leak. 75 img.get()->Release(); 76 77 img->SetOpaqueRect(GetOpaqueRect()); 78 79 return img.forget().downcast<gfxImageSurface>(); 80 } 81 82 gfxQuartzSurface::~gfxQuartzSurface() { CGContextRelease(mCGContext); }