1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/2d/Factory.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,732 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "2D.h" 1.10 + 1.11 +#ifdef USE_CAIRO 1.12 +#include "DrawTargetCairo.h" 1.13 +#include "ScaledFontCairo.h" 1.14 +#endif 1.15 + 1.16 +#ifdef USE_SKIA 1.17 +#include "DrawTargetSkia.h" 1.18 +#include "ScaledFontBase.h" 1.19 +#ifdef MOZ_ENABLE_FREETYPE 1.20 +#define USE_SKIA_FREETYPE 1.21 +#include "ScaledFontCairo.h" 1.22 +#endif 1.23 +#endif 1.24 + 1.25 +#if defined(WIN32) && defined(USE_SKIA) 1.26 +#include "ScaledFontWin.h" 1.27 +#endif 1.28 + 1.29 +#ifdef XP_MACOSX 1.30 +#include "ScaledFontMac.h" 1.31 +#endif 1.32 + 1.33 + 1.34 +#ifdef XP_MACOSX 1.35 +#include "DrawTargetCG.h" 1.36 +#endif 1.37 + 1.38 +#ifdef WIN32 1.39 +#include "DrawTargetD2D.h" 1.40 +#ifdef USE_D2D1_1 1.41 +#include "DrawTargetD2D1.h" 1.42 +#endif 1.43 +#include "ScaledFontDWrite.h" 1.44 +#include <d3d10_1.h> 1.45 +#include "HelpersD2D.h" 1.46 +#endif 1.47 + 1.48 +#include "DrawTargetDual.h" 1.49 +#include "DrawTargetRecording.h" 1.50 + 1.51 +#include "SourceSurfaceRawData.h" 1.52 + 1.53 +#include "DrawEventRecorder.h" 1.54 + 1.55 +#include "Logging.h" 1.56 + 1.57 +#include "mozilla/CheckedInt.h" 1.58 + 1.59 +#if defined(DEBUG) || defined(PR_LOGGING) 1.60 +GFX2D_API PRLogModuleInfo * 1.61 +GetGFX2DLog() 1.62 +{ 1.63 + static PRLogModuleInfo *sLog; 1.64 + if (!sLog) 1.65 + sLog = PR_NewLogModule("gfx2d"); 1.66 + return sLog; 1.67 +} 1.68 +#endif 1.69 + 1.70 +// The following code was largely taken from xpcom/glue/SSE.cpp and 1.71 +// made a little simpler. 1.72 +enum CPUIDRegister { eax = 0, ebx = 1, ecx = 2, edx = 3 }; 1.73 + 1.74 +#ifdef HAVE_CPUID_H 1.75 + 1.76 +#if !(defined(__SSE2__) || defined(_M_X64) || \ 1.77 + (defined(_M_IX86_FP) && _M_IX86_FP >= 2)) 1.78 +// cpuid.h is available on gcc 4.3 and higher on i386 and x86_64 1.79 +#include <cpuid.h> 1.80 + 1.81 +static inline bool 1.82 +HasCPUIDBit(unsigned int level, CPUIDRegister reg, unsigned int bit) 1.83 +{ 1.84 + unsigned int regs[4]; 1.85 + return __get_cpuid(level, ®s[0], ®s[1], ®s[2], ®s[3]) && 1.86 + (regs[reg] & bit); 1.87 +} 1.88 +#endif 1.89 + 1.90 +#define HAVE_CPU_DETECTION 1.91 +#else 1.92 + 1.93 +#if defined(_MSC_VER) && _MSC_VER >= 1600 && (defined(_M_IX86) || defined(_M_AMD64)) 1.94 +// MSVC 2005 or later supports __cpuid by intrin.h 1.95 +// But it does't work on MSVC 2005 with SDK 7.1 (Bug 753772) 1.96 +#include <intrin.h> 1.97 + 1.98 +#define HAVE_CPU_DETECTION 1.99 +#elif defined(__SUNPRO_CC) && (defined(__i386) || defined(__x86_64__)) 1.100 + 1.101 +// Define a function identical to MSVC function. 1.102 +#ifdef __i386 1.103 +static void 1.104 +__cpuid(int CPUInfo[4], int InfoType) 1.105 +{ 1.106 + asm ( 1.107 + "xchg %esi, %ebx\n" 1.108 + "cpuid\n" 1.109 + "movl %eax, (%edi)\n" 1.110 + "movl %ebx, 4(%edi)\n" 1.111 + "movl %ecx, 8(%edi)\n" 1.112 + "movl %edx, 12(%edi)\n" 1.113 + "xchg %esi, %ebx\n" 1.114 + : 1.115 + : "a"(InfoType), // %eax 1.116 + "D"(CPUInfo) // %edi 1.117 + : "%ecx", "%edx", "%esi" 1.118 + ); 1.119 +} 1.120 +#else 1.121 +static void 1.122 +__cpuid(int CPUInfo[4], int InfoType) 1.123 +{ 1.124 + asm ( 1.125 + "xchg %rsi, %rbx\n" 1.126 + "cpuid\n" 1.127 + "movl %eax, (%rdi)\n" 1.128 + "movl %ebx, 4(%rdi)\n" 1.129 + "movl %ecx, 8(%rdi)\n" 1.130 + "movl %edx, 12(%rdi)\n" 1.131 + "xchg %rsi, %rbx\n" 1.132 + : 1.133 + : "a"(InfoType), // %eax 1.134 + "D"(CPUInfo) // %rdi 1.135 + : "%ecx", "%edx", "%rsi" 1.136 + ); 1.137 +} 1.138 + 1.139 +#define HAVE_CPU_DETECTION 1.140 +#endif 1.141 +#endif 1.142 + 1.143 +#ifdef HAVE_CPU_DETECTION 1.144 +static inline bool 1.145 +HasCPUIDBit(unsigned int level, CPUIDRegister reg, unsigned int bit) 1.146 +{ 1.147 + // Check that the level in question is supported. 1.148 + volatile int regs[4]; 1.149 + __cpuid((int *)regs, level & 0x80000000u); 1.150 + if (unsigned(regs[0]) < level) 1.151 + return false; 1.152 + __cpuid((int *)regs, level); 1.153 + return !!(unsigned(regs[reg]) & bit); 1.154 +} 1.155 +#endif 1.156 +#endif 1.157 + 1.158 +namespace mozilla { 1.159 +namespace gfx { 1.160 + 1.161 +// XXX - Need to define an API to set this. 1.162 +GFX2D_API int sGfxLogLevel = LOG_DEBUG; 1.163 + 1.164 +#ifdef WIN32 1.165 +ID3D10Device1 *Factory::mD3D10Device; 1.166 +#ifdef USE_D2D1_1 1.167 +ID3D11Device *Factory::mD3D11Device; 1.168 +ID2D1Device *Factory::mD2D1Device; 1.169 +#endif 1.170 +#endif 1.171 + 1.172 +DrawEventRecorder *Factory::mRecorder; 1.173 + 1.174 +bool 1.175 +Factory::HasSSE2() 1.176 +{ 1.177 +#if defined(__SSE2__) || defined(_M_X64) || \ 1.178 + (defined(_M_IX86_FP) && _M_IX86_FP >= 2) 1.179 + // gcc with -msse2 (default on OSX and x86-64) 1.180 + // cl.exe with -arch:SSE2 (default on x64 compiler) 1.181 + return true; 1.182 +#elif defined(HAVE_CPU_DETECTION) 1.183 + return HasCPUIDBit(1u, edx, (1u<<26)); 1.184 +#else 1.185 + return false; 1.186 +#endif 1.187 +} 1.188 + 1.189 +bool 1.190 +Factory::CheckSurfaceSize(const IntSize &sz, int32_t limit) 1.191 +{ 1.192 + if (sz.width < 0 || sz.height < 0) { 1.193 + gfxDebug() << "Surface width or height < 0!"; 1.194 + return false; 1.195 + } 1.196 + 1.197 + // reject images with sides bigger than limit 1.198 + if (limit && (sz.width > limit || sz.height > limit)) { 1.199 + gfxDebug() << "Surface size too large (exceeds caller's limit)!"; 1.200 + return false; 1.201 + } 1.202 + 1.203 + // make sure the surface area doesn't overflow a int32_t 1.204 + CheckedInt<int32_t> tmp = sz.width; 1.205 + tmp *= sz.height; 1.206 + if (!tmp.isValid()) { 1.207 + gfxDebug() << "Surface size too large (would overflow)!"; 1.208 + return false; 1.209 + } 1.210 + 1.211 + // assuming 4 bytes per pixel, make sure the allocation size 1.212 + // doesn't overflow a int32_t either 1.213 + CheckedInt<int32_t> stride = sz.width; 1.214 + stride *= 4; 1.215 + 1.216 + // When aligning the stride to 16 bytes, it can grow by up to 15 bytes. 1.217 + stride += 16 - 1; 1.218 + 1.219 + if (!stride.isValid()) { 1.220 + gfxDebug() << "Surface size too large (stride overflows int32_t)!"; 1.221 + return false; 1.222 + } 1.223 + 1.224 + CheckedInt<int32_t> numBytes = GetAlignedStride<16>(sz.width * 4); 1.225 + numBytes *= sz.height; 1.226 + if (!numBytes.isValid()) { 1.227 + gfxDebug() << "Surface size too large (allocation size would overflow int32_t)!"; 1.228 + return false; 1.229 + } 1.230 + 1.231 + return true; 1.232 +} 1.233 + 1.234 +TemporaryRef<DrawTarget> 1.235 +Factory::CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat) 1.236 +{ 1.237 + if (!CheckSurfaceSize(aSize)) { 1.238 + return nullptr; 1.239 + } 1.240 + 1.241 + RefPtr<DrawTarget> retVal; 1.242 + switch (aBackend) { 1.243 +#ifdef WIN32 1.244 + case BackendType::DIRECT2D: 1.245 + { 1.246 + RefPtr<DrawTargetD2D> newTarget; 1.247 + newTarget = new DrawTargetD2D(); 1.248 + if (newTarget->Init(aSize, aFormat)) { 1.249 + retVal = newTarget; 1.250 + } 1.251 + break; 1.252 + } 1.253 +#ifdef USE_D2D1_1 1.254 + case BackendType::DIRECT2D1_1: 1.255 + { 1.256 + RefPtr<DrawTargetD2D1> newTarget; 1.257 + newTarget = new DrawTargetD2D1(); 1.258 + if (newTarget->Init(aSize, aFormat)) { 1.259 + retVal = newTarget; 1.260 + } 1.261 + break; 1.262 + } 1.263 +#endif 1.264 +#elif defined XP_MACOSX 1.265 + case BackendType::COREGRAPHICS: 1.266 + case BackendType::COREGRAPHICS_ACCELERATED: 1.267 + { 1.268 + RefPtr<DrawTargetCG> newTarget; 1.269 + newTarget = new DrawTargetCG(); 1.270 + if (newTarget->Init(aBackend, aSize, aFormat)) { 1.271 + retVal = newTarget; 1.272 + } 1.273 + break; 1.274 + } 1.275 +#endif 1.276 +#ifdef USE_SKIA 1.277 + case BackendType::SKIA: 1.278 + { 1.279 + RefPtr<DrawTargetSkia> newTarget; 1.280 + newTarget = new DrawTargetSkia(); 1.281 + if (newTarget->Init(aSize, aFormat)) { 1.282 + retVal = newTarget; 1.283 + } 1.284 + break; 1.285 + } 1.286 +#endif 1.287 +#ifdef USE_CAIRO 1.288 + case BackendType::CAIRO: 1.289 + { 1.290 + RefPtr<DrawTargetCairo> newTarget; 1.291 + newTarget = new DrawTargetCairo(); 1.292 + if (newTarget->Init(aSize, aFormat)) { 1.293 + retVal = newTarget; 1.294 + } 1.295 + break; 1.296 + } 1.297 +#endif 1.298 + default: 1.299 + gfxDebug() << "Invalid draw target type specified."; 1.300 + return nullptr; 1.301 + } 1.302 + 1.303 + if (mRecorder && retVal) { 1.304 + RefPtr<DrawTarget> recordDT; 1.305 + recordDT = new DrawTargetRecording(mRecorder, retVal); 1.306 + return recordDT; 1.307 + } 1.308 + 1.309 + if (!retVal) { 1.310 + // Failed 1.311 + gfxDebug() << "Failed to create DrawTarget, Type: " << int(aBackend) << " Size: " << aSize; 1.312 + } 1.313 + 1.314 + return retVal; 1.315 +} 1.316 + 1.317 +TemporaryRef<DrawTarget> 1.318 +Factory::CreateRecordingDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT) 1.319 +{ 1.320 + return new DrawTargetRecording(aRecorder, aDT); 1.321 +} 1.322 + 1.323 +TemporaryRef<DrawTarget> 1.324 +Factory::CreateDrawTargetForData(BackendType aBackend, 1.325 + unsigned char *aData, 1.326 + const IntSize &aSize, 1.327 + int32_t aStride, 1.328 + SurfaceFormat aFormat) 1.329 +{ 1.330 + if (!CheckSurfaceSize(aSize)) { 1.331 + return nullptr; 1.332 + } 1.333 + 1.334 + RefPtr<DrawTarget> retVal; 1.335 + 1.336 + switch (aBackend) { 1.337 +#ifdef USE_SKIA 1.338 + case BackendType::SKIA: 1.339 + { 1.340 + RefPtr<DrawTargetSkia> newTarget; 1.341 + newTarget = new DrawTargetSkia(); 1.342 + newTarget->Init(aData, aSize, aStride, aFormat); 1.343 + retVal = newTarget; 1.344 + break; 1.345 + } 1.346 +#endif 1.347 +#ifdef XP_MACOSX 1.348 + case BackendType::COREGRAPHICS: 1.349 + { 1.350 + RefPtr<DrawTargetCG> newTarget = new DrawTargetCG(); 1.351 + if (newTarget->Init(aBackend, aData, aSize, aStride, aFormat)) 1.352 + return newTarget; 1.353 + break; 1.354 + } 1.355 +#endif 1.356 +#ifdef USE_CAIRO 1.357 + case BackendType::CAIRO: 1.358 + { 1.359 + RefPtr<DrawTargetCairo> newTarget; 1.360 + newTarget = new DrawTargetCairo(); 1.361 + if (newTarget->Init(aData, aSize, aStride, aFormat)) { 1.362 + retVal = newTarget; 1.363 + } 1.364 + break; 1.365 + } 1.366 +#endif 1.367 + default: 1.368 + gfxDebug() << "Invalid draw target type specified."; 1.369 + return nullptr; 1.370 + } 1.371 + 1.372 + if (mRecorder && retVal) { 1.373 + RefPtr<DrawTarget> recordDT = new DrawTargetRecording(mRecorder, retVal, true); 1.374 + return recordDT; 1.375 + } 1.376 + 1.377 + if (!retVal) { 1.378 + gfxDebug() << "Failed to create DrawTarget, Type: " << int(aBackend) << " Size: " << aSize; 1.379 + } 1.380 + 1.381 + return retVal; 1.382 +} 1.383 + 1.384 +TemporaryRef<ScaledFont> 1.385 +Factory::CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSize) 1.386 +{ 1.387 + switch (aNativeFont.mType) { 1.388 +#ifdef WIN32 1.389 + case NativeFontType::DWRITE_FONT_FACE: 1.390 + { 1.391 + return new ScaledFontDWrite(static_cast<IDWriteFontFace*>(aNativeFont.mFont), aSize); 1.392 + } 1.393 +#if defined(USE_CAIRO) || defined(USE_SKIA) 1.394 + case NativeFontType::GDI_FONT_FACE: 1.395 + { 1.396 + return new ScaledFontWin(static_cast<LOGFONT*>(aNativeFont.mFont), aSize); 1.397 + } 1.398 +#endif 1.399 +#endif 1.400 +#ifdef XP_MACOSX 1.401 + case NativeFontType::MAC_FONT_FACE: 1.402 + { 1.403 + return new ScaledFontMac(static_cast<CGFontRef>(aNativeFont.mFont), aSize); 1.404 + } 1.405 +#endif 1.406 +#if defined(USE_CAIRO) || defined(USE_SKIA_FREETYPE) 1.407 + case NativeFontType::CAIRO_FONT_FACE: 1.408 + { 1.409 + return new ScaledFontCairo(static_cast<cairo_scaled_font_t*>(aNativeFont.mFont), aSize); 1.410 + } 1.411 +#endif 1.412 + default: 1.413 + gfxWarning() << "Invalid native font type specified."; 1.414 + return nullptr; 1.415 + } 1.416 +} 1.417 + 1.418 +TemporaryRef<ScaledFont> 1.419 +Factory::CreateScaledFontForTrueTypeData(uint8_t *aData, uint32_t aSize, 1.420 + uint32_t aFaceIndex, Float aGlyphSize, 1.421 + FontType aType) 1.422 +{ 1.423 + switch (aType) { 1.424 +#ifdef WIN32 1.425 + case FontType::DWRITE: 1.426 + { 1.427 + return new ScaledFontDWrite(aData, aSize, aFaceIndex, aGlyphSize); 1.428 + } 1.429 +#endif 1.430 + default: 1.431 + gfxWarning() << "Unable to create requested font type from truetype data"; 1.432 + return nullptr; 1.433 + } 1.434 +} 1.435 + 1.436 +TemporaryRef<ScaledFont> 1.437 +Factory::CreateScaledFontWithCairo(const NativeFont& aNativeFont, Float aSize, cairo_scaled_font_t* aScaledFont) 1.438 +{ 1.439 +#ifdef USE_CAIRO 1.440 + // In theory, we could pull the NativeFont out of the cairo_scaled_font_t*, 1.441 + // but that would require a lot of code that would be otherwise repeated in 1.442 + // various backends. 1.443 + // Therefore, we just reuse CreateScaledFontForNativeFont's implementation. 1.444 + RefPtr<ScaledFont> font = CreateScaledFontForNativeFont(aNativeFont, aSize); 1.445 + static_cast<ScaledFontBase*>(font.get())->SetCairoScaledFont(aScaledFont); 1.446 + return font; 1.447 +#else 1.448 + return nullptr; 1.449 +#endif 1.450 +} 1.451 + 1.452 +TemporaryRef<DrawTarget> 1.453 +Factory::CreateDualDrawTarget(DrawTarget *targetA, DrawTarget *targetB) 1.454 +{ 1.455 + RefPtr<DrawTarget> newTarget = 1.456 + new DrawTargetDual(targetA, targetB); 1.457 + 1.458 + RefPtr<DrawTarget> retVal = newTarget; 1.459 + 1.460 + if (mRecorder) { 1.461 + retVal = new DrawTargetRecording(mRecorder, retVal); 1.462 + } 1.463 + 1.464 + return retVal; 1.465 +} 1.466 + 1.467 + 1.468 +#ifdef WIN32 1.469 +TemporaryRef<DrawTarget> 1.470 +Factory::CreateDrawTargetForD3D10Texture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat) 1.471 +{ 1.472 + RefPtr<DrawTargetD2D> newTarget; 1.473 + 1.474 + newTarget = new DrawTargetD2D(); 1.475 + if (newTarget->Init(aTexture, aFormat)) { 1.476 + RefPtr<DrawTarget> retVal = newTarget; 1.477 + 1.478 + if (mRecorder) { 1.479 + retVal = new DrawTargetRecording(mRecorder, retVal, true); 1.480 + } 1.481 + 1.482 + return retVal; 1.483 + } 1.484 + 1.485 + gfxWarning() << "Failed to create draw target for D3D10 texture."; 1.486 + 1.487 + // Failed 1.488 + return nullptr; 1.489 +} 1.490 + 1.491 +TemporaryRef<DrawTarget> 1.492 +Factory::CreateDualDrawTargetForD3D10Textures(ID3D10Texture2D *aTextureA, 1.493 + ID3D10Texture2D *aTextureB, 1.494 + SurfaceFormat aFormat) 1.495 +{ 1.496 + RefPtr<DrawTargetD2D> newTargetA; 1.497 + RefPtr<DrawTargetD2D> newTargetB; 1.498 + 1.499 + newTargetA = new DrawTargetD2D(); 1.500 + if (!newTargetA->Init(aTextureA, aFormat)) { 1.501 + gfxWarning() << "Failed to create draw target for D3D10 texture."; 1.502 + return nullptr; 1.503 + } 1.504 + 1.505 + newTargetB = new DrawTargetD2D(); 1.506 + if (!newTargetB->Init(aTextureB, aFormat)) { 1.507 + gfxWarning() << "Failed to create draw target for D3D10 texture."; 1.508 + return nullptr; 1.509 + } 1.510 + 1.511 + RefPtr<DrawTarget> newTarget = 1.512 + new DrawTargetDual(newTargetA, newTargetB); 1.513 + 1.514 + RefPtr<DrawTarget> retVal = newTarget; 1.515 + 1.516 + if (mRecorder) { 1.517 + retVal = new DrawTargetRecording(mRecorder, retVal); 1.518 + } 1.519 + 1.520 + return retVal; 1.521 +} 1.522 + 1.523 +void 1.524 +Factory::SetDirect3D10Device(ID3D10Device1 *aDevice) 1.525 +{ 1.526 + // do not throw on failure; return error codes and disconnect the device 1.527 + // On Windows 8 error codes are the default, but on Windows 7 the 1.528 + // default is to throw (or perhaps only with some drivers?) 1.529 + aDevice->SetExceptionMode(0); 1.530 + mD3D10Device = aDevice; 1.531 +} 1.532 + 1.533 +ID3D10Device1* 1.534 +Factory::GetDirect3D10Device() 1.535 +{ 1.536 +#ifdef DEBUG 1.537 + UINT mode = mD3D10Device->GetExceptionMode(); 1.538 + MOZ_ASSERT(0 == mode); 1.539 +#endif 1.540 + return mD3D10Device; 1.541 +} 1.542 + 1.543 +#ifdef USE_D2D1_1 1.544 +void 1.545 +Factory::SetDirect3D11Device(ID3D11Device *aDevice) 1.546 +{ 1.547 + mD3D11Device = aDevice; 1.548 + 1.549 + RefPtr<ID2D1Factory1> factory = D2DFactory1(); 1.550 + 1.551 + RefPtr<IDXGIDevice> device; 1.552 + aDevice->QueryInterface((IDXGIDevice**)byRef(device)); 1.553 + factory->CreateDevice(device, &mD2D1Device); 1.554 +} 1.555 + 1.556 +ID3D11Device* 1.557 +Factory::GetDirect3D11Device() 1.558 +{ 1.559 + return mD3D11Device; 1.560 +} 1.561 + 1.562 +ID2D1Device* 1.563 +Factory::GetD2D1Device() 1.564 +{ 1.565 + return mD2D1Device; 1.566 +} 1.567 +#endif 1.568 + 1.569 +TemporaryRef<GlyphRenderingOptions> 1.570 +Factory::CreateDWriteGlyphRenderingOptions(IDWriteRenderingParams *aParams) 1.571 +{ 1.572 + RefPtr<GlyphRenderingOptions> options = 1.573 + new GlyphRenderingOptionsDWrite(aParams); 1.574 + 1.575 + return options; 1.576 +} 1.577 + 1.578 +uint64_t 1.579 +Factory::GetD2DVRAMUsageDrawTarget() 1.580 +{ 1.581 + return DrawTargetD2D::mVRAMUsageDT; 1.582 +} 1.583 + 1.584 +uint64_t 1.585 +Factory::GetD2DVRAMUsageSourceSurface() 1.586 +{ 1.587 + return DrawTargetD2D::mVRAMUsageSS; 1.588 +} 1.589 + 1.590 +void 1.591 +Factory::D2DCleanup() 1.592 +{ 1.593 + DrawTargetD2D::CleanupD2D(); 1.594 +} 1.595 + 1.596 +#endif // XP_WIN 1.597 + 1.598 +#ifdef USE_SKIA_GPU 1.599 +TemporaryRef<DrawTarget> 1.600 +Factory::CreateDrawTargetSkiaWithGrContext(GrContext* aGrContext, 1.601 + const IntSize &aSize, 1.602 + SurfaceFormat aFormat) 1.603 +{ 1.604 + RefPtr<DrawTarget> newTarget = new DrawTargetSkia(); 1.605 + if (!newTarget->InitWithGrContext(aGrContext, aSize, aFormat)) { 1.606 + return nullptr; 1.607 + } 1.608 + return newTarget; 1.609 +} 1.610 + 1.611 +#endif // USE_SKIA_GPU 1.612 + 1.613 +void 1.614 +Factory::PurgeAllCaches() 1.615 +{ 1.616 +} 1.617 + 1.618 +#ifdef USE_SKIA_FREETYPE 1.619 +TemporaryRef<GlyphRenderingOptions> 1.620 +Factory::CreateCairoGlyphRenderingOptions(FontHinting aHinting, bool aAutoHinting) 1.621 +{ 1.622 + RefPtr<GlyphRenderingOptionsCairo> options = 1.623 + new GlyphRenderingOptionsCairo(); 1.624 + 1.625 + options->SetHinting(aHinting); 1.626 + options->SetAutoHinting(aAutoHinting); 1.627 + return options; 1.628 +} 1.629 +#endif 1.630 + 1.631 +TemporaryRef<DrawTarget> 1.632 +Factory::CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat) 1.633 +{ 1.634 + RefPtr<DrawTarget> retVal; 1.635 + 1.636 +#ifdef USE_CAIRO 1.637 + RefPtr<DrawTargetCairo> newTarget = new DrawTargetCairo(); 1.638 + 1.639 + if (newTarget->Init(aSurface, aSize, aFormat)) { 1.640 + retVal = newTarget; 1.641 + } 1.642 + 1.643 + if (mRecorder && retVal) { 1.644 + RefPtr<DrawTarget> recordDT = new DrawTargetRecording(mRecorder, retVal, true); 1.645 + return recordDT; 1.646 + } 1.647 +#endif 1.648 + return retVal; 1.649 +} 1.650 + 1.651 +#ifdef XP_MACOSX 1.652 +TemporaryRef<DrawTarget> 1.653 +Factory::CreateDrawTargetForCairoCGContext(CGContextRef cg, const IntSize& aSize) 1.654 +{ 1.655 + RefPtr<DrawTarget> retVal; 1.656 + 1.657 + RefPtr<DrawTargetCG> newTarget = new DrawTargetCG(); 1.658 + 1.659 + if (newTarget->Init(cg, aSize)) { 1.660 + retVal = newTarget; 1.661 + } 1.662 + 1.663 + if (mRecorder && retVal) { 1.664 + RefPtr<DrawTarget> recordDT = new DrawTargetRecording(mRecorder, retVal); 1.665 + return recordDT; 1.666 + } 1.667 + return retVal; 1.668 +} 1.669 +#endif 1.670 + 1.671 +TemporaryRef<DataSourceSurface> 1.672 +Factory::CreateWrappingDataSourceSurface(uint8_t *aData, int32_t aStride, 1.673 + const IntSize &aSize, 1.674 + SurfaceFormat aFormat) 1.675 +{ 1.676 + if (aSize.width <= 0 || aSize.height <= 0) { 1.677 + return nullptr; 1.678 + } 1.679 + 1.680 + RefPtr<SourceSurfaceRawData> newSurf = new SourceSurfaceRawData(); 1.681 + 1.682 + if (newSurf->InitWrappingData(aData, aSize, aStride, aFormat, false)) { 1.683 + return newSurf; 1.684 + } 1.685 + 1.686 + return nullptr; 1.687 +} 1.688 + 1.689 +TemporaryRef<DataSourceSurface> 1.690 +Factory::CreateDataSourceSurface(const IntSize &aSize, 1.691 + SurfaceFormat aFormat) 1.692 +{ 1.693 + if (!CheckSurfaceSize(aSize)) { 1.694 + return nullptr; 1.695 + } 1.696 + 1.697 + RefPtr<SourceSurfaceAlignedRawData> newSurf = new SourceSurfaceAlignedRawData(); 1.698 + if (newSurf->Init(aSize, aFormat)) { 1.699 + return newSurf; 1.700 + } 1.701 + 1.702 + return nullptr; 1.703 +} 1.704 + 1.705 +TemporaryRef<DataSourceSurface> 1.706 +Factory::CreateDataSourceSurfaceWithStride(const IntSize &aSize, 1.707 + SurfaceFormat aFormat, 1.708 + int32_t aStride) 1.709 +{ 1.710 + if (aStride < aSize.width * BytesPerPixel(aFormat)) { 1.711 + return nullptr; 1.712 + } 1.713 + 1.714 + RefPtr<SourceSurfaceAlignedRawData> newSurf = new SourceSurfaceAlignedRawData(); 1.715 + if (newSurf->InitWithStride(aSize, aFormat, aStride)) { 1.716 + return newSurf; 1.717 + } 1.718 + 1.719 + return nullptr; 1.720 +} 1.721 + 1.722 +TemporaryRef<DrawEventRecorder> 1.723 +Factory::CreateEventRecorderForFile(const char *aFilename) 1.724 +{ 1.725 + return new DrawEventRecorderFile(aFilename); 1.726 +} 1.727 + 1.728 +void 1.729 +Factory::SetGlobalEventRecorder(DrawEventRecorder *aRecorder) 1.730 +{ 1.731 + mRecorder = aRecorder; 1.732 +} 1.733 + 1.734 +} 1.735 +}