gfx/2d/Factory.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "2D.h"
michael@0 7
michael@0 8 #ifdef USE_CAIRO
michael@0 9 #include "DrawTargetCairo.h"
michael@0 10 #include "ScaledFontCairo.h"
michael@0 11 #endif
michael@0 12
michael@0 13 #ifdef USE_SKIA
michael@0 14 #include "DrawTargetSkia.h"
michael@0 15 #include "ScaledFontBase.h"
michael@0 16 #ifdef MOZ_ENABLE_FREETYPE
michael@0 17 #define USE_SKIA_FREETYPE
michael@0 18 #include "ScaledFontCairo.h"
michael@0 19 #endif
michael@0 20 #endif
michael@0 21
michael@0 22 #if defined(WIN32) && defined(USE_SKIA)
michael@0 23 #include "ScaledFontWin.h"
michael@0 24 #endif
michael@0 25
michael@0 26 #ifdef XP_MACOSX
michael@0 27 #include "ScaledFontMac.h"
michael@0 28 #endif
michael@0 29
michael@0 30
michael@0 31 #ifdef XP_MACOSX
michael@0 32 #include "DrawTargetCG.h"
michael@0 33 #endif
michael@0 34
michael@0 35 #ifdef WIN32
michael@0 36 #include "DrawTargetD2D.h"
michael@0 37 #ifdef USE_D2D1_1
michael@0 38 #include "DrawTargetD2D1.h"
michael@0 39 #endif
michael@0 40 #include "ScaledFontDWrite.h"
michael@0 41 #include <d3d10_1.h>
michael@0 42 #include "HelpersD2D.h"
michael@0 43 #endif
michael@0 44
michael@0 45 #include "DrawTargetDual.h"
michael@0 46 #include "DrawTargetRecording.h"
michael@0 47
michael@0 48 #include "SourceSurfaceRawData.h"
michael@0 49
michael@0 50 #include "DrawEventRecorder.h"
michael@0 51
michael@0 52 #include "Logging.h"
michael@0 53
michael@0 54 #include "mozilla/CheckedInt.h"
michael@0 55
michael@0 56 #if defined(DEBUG) || defined(PR_LOGGING)
michael@0 57 GFX2D_API PRLogModuleInfo *
michael@0 58 GetGFX2DLog()
michael@0 59 {
michael@0 60 static PRLogModuleInfo *sLog;
michael@0 61 if (!sLog)
michael@0 62 sLog = PR_NewLogModule("gfx2d");
michael@0 63 return sLog;
michael@0 64 }
michael@0 65 #endif
michael@0 66
michael@0 67 // The following code was largely taken from xpcom/glue/SSE.cpp and
michael@0 68 // made a little simpler.
michael@0 69 enum CPUIDRegister { eax = 0, ebx = 1, ecx = 2, edx = 3 };
michael@0 70
michael@0 71 #ifdef HAVE_CPUID_H
michael@0 72
michael@0 73 #if !(defined(__SSE2__) || defined(_M_X64) || \
michael@0 74 (defined(_M_IX86_FP) && _M_IX86_FP >= 2))
michael@0 75 // cpuid.h is available on gcc 4.3 and higher on i386 and x86_64
michael@0 76 #include <cpuid.h>
michael@0 77
michael@0 78 static inline bool
michael@0 79 HasCPUIDBit(unsigned int level, CPUIDRegister reg, unsigned int bit)
michael@0 80 {
michael@0 81 unsigned int regs[4];
michael@0 82 return __get_cpuid(level, &regs[0], &regs[1], &regs[2], &regs[3]) &&
michael@0 83 (regs[reg] & bit);
michael@0 84 }
michael@0 85 #endif
michael@0 86
michael@0 87 #define HAVE_CPU_DETECTION
michael@0 88 #else
michael@0 89
michael@0 90 #if defined(_MSC_VER) && _MSC_VER >= 1600 && (defined(_M_IX86) || defined(_M_AMD64))
michael@0 91 // MSVC 2005 or later supports __cpuid by intrin.h
michael@0 92 // But it does't work on MSVC 2005 with SDK 7.1 (Bug 753772)
michael@0 93 #include <intrin.h>
michael@0 94
michael@0 95 #define HAVE_CPU_DETECTION
michael@0 96 #elif defined(__SUNPRO_CC) && (defined(__i386) || defined(__x86_64__))
michael@0 97
michael@0 98 // Define a function identical to MSVC function.
michael@0 99 #ifdef __i386
michael@0 100 static void
michael@0 101 __cpuid(int CPUInfo[4], int InfoType)
michael@0 102 {
michael@0 103 asm (
michael@0 104 "xchg %esi, %ebx\n"
michael@0 105 "cpuid\n"
michael@0 106 "movl %eax, (%edi)\n"
michael@0 107 "movl %ebx, 4(%edi)\n"
michael@0 108 "movl %ecx, 8(%edi)\n"
michael@0 109 "movl %edx, 12(%edi)\n"
michael@0 110 "xchg %esi, %ebx\n"
michael@0 111 :
michael@0 112 : "a"(InfoType), // %eax
michael@0 113 "D"(CPUInfo) // %edi
michael@0 114 : "%ecx", "%edx", "%esi"
michael@0 115 );
michael@0 116 }
michael@0 117 #else
michael@0 118 static void
michael@0 119 __cpuid(int CPUInfo[4], int InfoType)
michael@0 120 {
michael@0 121 asm (
michael@0 122 "xchg %rsi, %rbx\n"
michael@0 123 "cpuid\n"
michael@0 124 "movl %eax, (%rdi)\n"
michael@0 125 "movl %ebx, 4(%rdi)\n"
michael@0 126 "movl %ecx, 8(%rdi)\n"
michael@0 127 "movl %edx, 12(%rdi)\n"
michael@0 128 "xchg %rsi, %rbx\n"
michael@0 129 :
michael@0 130 : "a"(InfoType), // %eax
michael@0 131 "D"(CPUInfo) // %rdi
michael@0 132 : "%ecx", "%edx", "%rsi"
michael@0 133 );
michael@0 134 }
michael@0 135
michael@0 136 #define HAVE_CPU_DETECTION
michael@0 137 #endif
michael@0 138 #endif
michael@0 139
michael@0 140 #ifdef HAVE_CPU_DETECTION
michael@0 141 static inline bool
michael@0 142 HasCPUIDBit(unsigned int level, CPUIDRegister reg, unsigned int bit)
michael@0 143 {
michael@0 144 // Check that the level in question is supported.
michael@0 145 volatile int regs[4];
michael@0 146 __cpuid((int *)regs, level & 0x80000000u);
michael@0 147 if (unsigned(regs[0]) < level)
michael@0 148 return false;
michael@0 149 __cpuid((int *)regs, level);
michael@0 150 return !!(unsigned(regs[reg]) & bit);
michael@0 151 }
michael@0 152 #endif
michael@0 153 #endif
michael@0 154
michael@0 155 namespace mozilla {
michael@0 156 namespace gfx {
michael@0 157
michael@0 158 // XXX - Need to define an API to set this.
michael@0 159 GFX2D_API int sGfxLogLevel = LOG_DEBUG;
michael@0 160
michael@0 161 #ifdef WIN32
michael@0 162 ID3D10Device1 *Factory::mD3D10Device;
michael@0 163 #ifdef USE_D2D1_1
michael@0 164 ID3D11Device *Factory::mD3D11Device;
michael@0 165 ID2D1Device *Factory::mD2D1Device;
michael@0 166 #endif
michael@0 167 #endif
michael@0 168
michael@0 169 DrawEventRecorder *Factory::mRecorder;
michael@0 170
michael@0 171 bool
michael@0 172 Factory::HasSSE2()
michael@0 173 {
michael@0 174 #if defined(__SSE2__) || defined(_M_X64) || \
michael@0 175 (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
michael@0 176 // gcc with -msse2 (default on OSX and x86-64)
michael@0 177 // cl.exe with -arch:SSE2 (default on x64 compiler)
michael@0 178 return true;
michael@0 179 #elif defined(HAVE_CPU_DETECTION)
michael@0 180 return HasCPUIDBit(1u, edx, (1u<<26));
michael@0 181 #else
michael@0 182 return false;
michael@0 183 #endif
michael@0 184 }
michael@0 185
michael@0 186 bool
michael@0 187 Factory::CheckSurfaceSize(const IntSize &sz, int32_t limit)
michael@0 188 {
michael@0 189 if (sz.width < 0 || sz.height < 0) {
michael@0 190 gfxDebug() << "Surface width or height < 0!";
michael@0 191 return false;
michael@0 192 }
michael@0 193
michael@0 194 // reject images with sides bigger than limit
michael@0 195 if (limit && (sz.width > limit || sz.height > limit)) {
michael@0 196 gfxDebug() << "Surface size too large (exceeds caller's limit)!";
michael@0 197 return false;
michael@0 198 }
michael@0 199
michael@0 200 // make sure the surface area doesn't overflow a int32_t
michael@0 201 CheckedInt<int32_t> tmp = sz.width;
michael@0 202 tmp *= sz.height;
michael@0 203 if (!tmp.isValid()) {
michael@0 204 gfxDebug() << "Surface size too large (would overflow)!";
michael@0 205 return false;
michael@0 206 }
michael@0 207
michael@0 208 // assuming 4 bytes per pixel, make sure the allocation size
michael@0 209 // doesn't overflow a int32_t either
michael@0 210 CheckedInt<int32_t> stride = sz.width;
michael@0 211 stride *= 4;
michael@0 212
michael@0 213 // When aligning the stride to 16 bytes, it can grow by up to 15 bytes.
michael@0 214 stride += 16 - 1;
michael@0 215
michael@0 216 if (!stride.isValid()) {
michael@0 217 gfxDebug() << "Surface size too large (stride overflows int32_t)!";
michael@0 218 return false;
michael@0 219 }
michael@0 220
michael@0 221 CheckedInt<int32_t> numBytes = GetAlignedStride<16>(sz.width * 4);
michael@0 222 numBytes *= sz.height;
michael@0 223 if (!numBytes.isValid()) {
michael@0 224 gfxDebug() << "Surface size too large (allocation size would overflow int32_t)!";
michael@0 225 return false;
michael@0 226 }
michael@0 227
michael@0 228 return true;
michael@0 229 }
michael@0 230
michael@0 231 TemporaryRef<DrawTarget>
michael@0 232 Factory::CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat)
michael@0 233 {
michael@0 234 if (!CheckSurfaceSize(aSize)) {
michael@0 235 return nullptr;
michael@0 236 }
michael@0 237
michael@0 238 RefPtr<DrawTarget> retVal;
michael@0 239 switch (aBackend) {
michael@0 240 #ifdef WIN32
michael@0 241 case BackendType::DIRECT2D:
michael@0 242 {
michael@0 243 RefPtr<DrawTargetD2D> newTarget;
michael@0 244 newTarget = new DrawTargetD2D();
michael@0 245 if (newTarget->Init(aSize, aFormat)) {
michael@0 246 retVal = newTarget;
michael@0 247 }
michael@0 248 break;
michael@0 249 }
michael@0 250 #ifdef USE_D2D1_1
michael@0 251 case BackendType::DIRECT2D1_1:
michael@0 252 {
michael@0 253 RefPtr<DrawTargetD2D1> newTarget;
michael@0 254 newTarget = new DrawTargetD2D1();
michael@0 255 if (newTarget->Init(aSize, aFormat)) {
michael@0 256 retVal = newTarget;
michael@0 257 }
michael@0 258 break;
michael@0 259 }
michael@0 260 #endif
michael@0 261 #elif defined XP_MACOSX
michael@0 262 case BackendType::COREGRAPHICS:
michael@0 263 case BackendType::COREGRAPHICS_ACCELERATED:
michael@0 264 {
michael@0 265 RefPtr<DrawTargetCG> newTarget;
michael@0 266 newTarget = new DrawTargetCG();
michael@0 267 if (newTarget->Init(aBackend, aSize, aFormat)) {
michael@0 268 retVal = newTarget;
michael@0 269 }
michael@0 270 break;
michael@0 271 }
michael@0 272 #endif
michael@0 273 #ifdef USE_SKIA
michael@0 274 case BackendType::SKIA:
michael@0 275 {
michael@0 276 RefPtr<DrawTargetSkia> newTarget;
michael@0 277 newTarget = new DrawTargetSkia();
michael@0 278 if (newTarget->Init(aSize, aFormat)) {
michael@0 279 retVal = newTarget;
michael@0 280 }
michael@0 281 break;
michael@0 282 }
michael@0 283 #endif
michael@0 284 #ifdef USE_CAIRO
michael@0 285 case BackendType::CAIRO:
michael@0 286 {
michael@0 287 RefPtr<DrawTargetCairo> newTarget;
michael@0 288 newTarget = new DrawTargetCairo();
michael@0 289 if (newTarget->Init(aSize, aFormat)) {
michael@0 290 retVal = newTarget;
michael@0 291 }
michael@0 292 break;
michael@0 293 }
michael@0 294 #endif
michael@0 295 default:
michael@0 296 gfxDebug() << "Invalid draw target type specified.";
michael@0 297 return nullptr;
michael@0 298 }
michael@0 299
michael@0 300 if (mRecorder && retVal) {
michael@0 301 RefPtr<DrawTarget> recordDT;
michael@0 302 recordDT = new DrawTargetRecording(mRecorder, retVal);
michael@0 303 return recordDT;
michael@0 304 }
michael@0 305
michael@0 306 if (!retVal) {
michael@0 307 // Failed
michael@0 308 gfxDebug() << "Failed to create DrawTarget, Type: " << int(aBackend) << " Size: " << aSize;
michael@0 309 }
michael@0 310
michael@0 311 return retVal;
michael@0 312 }
michael@0 313
michael@0 314 TemporaryRef<DrawTarget>
michael@0 315 Factory::CreateRecordingDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT)
michael@0 316 {
michael@0 317 return new DrawTargetRecording(aRecorder, aDT);
michael@0 318 }
michael@0 319
michael@0 320 TemporaryRef<DrawTarget>
michael@0 321 Factory::CreateDrawTargetForData(BackendType aBackend,
michael@0 322 unsigned char *aData,
michael@0 323 const IntSize &aSize,
michael@0 324 int32_t aStride,
michael@0 325 SurfaceFormat aFormat)
michael@0 326 {
michael@0 327 if (!CheckSurfaceSize(aSize)) {
michael@0 328 return nullptr;
michael@0 329 }
michael@0 330
michael@0 331 RefPtr<DrawTarget> retVal;
michael@0 332
michael@0 333 switch (aBackend) {
michael@0 334 #ifdef USE_SKIA
michael@0 335 case BackendType::SKIA:
michael@0 336 {
michael@0 337 RefPtr<DrawTargetSkia> newTarget;
michael@0 338 newTarget = new DrawTargetSkia();
michael@0 339 newTarget->Init(aData, aSize, aStride, aFormat);
michael@0 340 retVal = newTarget;
michael@0 341 break;
michael@0 342 }
michael@0 343 #endif
michael@0 344 #ifdef XP_MACOSX
michael@0 345 case BackendType::COREGRAPHICS:
michael@0 346 {
michael@0 347 RefPtr<DrawTargetCG> newTarget = new DrawTargetCG();
michael@0 348 if (newTarget->Init(aBackend, aData, aSize, aStride, aFormat))
michael@0 349 return newTarget;
michael@0 350 break;
michael@0 351 }
michael@0 352 #endif
michael@0 353 #ifdef USE_CAIRO
michael@0 354 case BackendType::CAIRO:
michael@0 355 {
michael@0 356 RefPtr<DrawTargetCairo> newTarget;
michael@0 357 newTarget = new DrawTargetCairo();
michael@0 358 if (newTarget->Init(aData, aSize, aStride, aFormat)) {
michael@0 359 retVal = newTarget;
michael@0 360 }
michael@0 361 break;
michael@0 362 }
michael@0 363 #endif
michael@0 364 default:
michael@0 365 gfxDebug() << "Invalid draw target type specified.";
michael@0 366 return nullptr;
michael@0 367 }
michael@0 368
michael@0 369 if (mRecorder && retVal) {
michael@0 370 RefPtr<DrawTarget> recordDT = new DrawTargetRecording(mRecorder, retVal, true);
michael@0 371 return recordDT;
michael@0 372 }
michael@0 373
michael@0 374 if (!retVal) {
michael@0 375 gfxDebug() << "Failed to create DrawTarget, Type: " << int(aBackend) << " Size: " << aSize;
michael@0 376 }
michael@0 377
michael@0 378 return retVal;
michael@0 379 }
michael@0 380
michael@0 381 TemporaryRef<ScaledFont>
michael@0 382 Factory::CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSize)
michael@0 383 {
michael@0 384 switch (aNativeFont.mType) {
michael@0 385 #ifdef WIN32
michael@0 386 case NativeFontType::DWRITE_FONT_FACE:
michael@0 387 {
michael@0 388 return new ScaledFontDWrite(static_cast<IDWriteFontFace*>(aNativeFont.mFont), aSize);
michael@0 389 }
michael@0 390 #if defined(USE_CAIRO) || defined(USE_SKIA)
michael@0 391 case NativeFontType::GDI_FONT_FACE:
michael@0 392 {
michael@0 393 return new ScaledFontWin(static_cast<LOGFONT*>(aNativeFont.mFont), aSize);
michael@0 394 }
michael@0 395 #endif
michael@0 396 #endif
michael@0 397 #ifdef XP_MACOSX
michael@0 398 case NativeFontType::MAC_FONT_FACE:
michael@0 399 {
michael@0 400 return new ScaledFontMac(static_cast<CGFontRef>(aNativeFont.mFont), aSize);
michael@0 401 }
michael@0 402 #endif
michael@0 403 #if defined(USE_CAIRO) || defined(USE_SKIA_FREETYPE)
michael@0 404 case NativeFontType::CAIRO_FONT_FACE:
michael@0 405 {
michael@0 406 return new ScaledFontCairo(static_cast<cairo_scaled_font_t*>(aNativeFont.mFont), aSize);
michael@0 407 }
michael@0 408 #endif
michael@0 409 default:
michael@0 410 gfxWarning() << "Invalid native font type specified.";
michael@0 411 return nullptr;
michael@0 412 }
michael@0 413 }
michael@0 414
michael@0 415 TemporaryRef<ScaledFont>
michael@0 416 Factory::CreateScaledFontForTrueTypeData(uint8_t *aData, uint32_t aSize,
michael@0 417 uint32_t aFaceIndex, Float aGlyphSize,
michael@0 418 FontType aType)
michael@0 419 {
michael@0 420 switch (aType) {
michael@0 421 #ifdef WIN32
michael@0 422 case FontType::DWRITE:
michael@0 423 {
michael@0 424 return new ScaledFontDWrite(aData, aSize, aFaceIndex, aGlyphSize);
michael@0 425 }
michael@0 426 #endif
michael@0 427 default:
michael@0 428 gfxWarning() << "Unable to create requested font type from truetype data";
michael@0 429 return nullptr;
michael@0 430 }
michael@0 431 }
michael@0 432
michael@0 433 TemporaryRef<ScaledFont>
michael@0 434 Factory::CreateScaledFontWithCairo(const NativeFont& aNativeFont, Float aSize, cairo_scaled_font_t* aScaledFont)
michael@0 435 {
michael@0 436 #ifdef USE_CAIRO
michael@0 437 // In theory, we could pull the NativeFont out of the cairo_scaled_font_t*,
michael@0 438 // but that would require a lot of code that would be otherwise repeated in
michael@0 439 // various backends.
michael@0 440 // Therefore, we just reuse CreateScaledFontForNativeFont's implementation.
michael@0 441 RefPtr<ScaledFont> font = CreateScaledFontForNativeFont(aNativeFont, aSize);
michael@0 442 static_cast<ScaledFontBase*>(font.get())->SetCairoScaledFont(aScaledFont);
michael@0 443 return font;
michael@0 444 #else
michael@0 445 return nullptr;
michael@0 446 #endif
michael@0 447 }
michael@0 448
michael@0 449 TemporaryRef<DrawTarget>
michael@0 450 Factory::CreateDualDrawTarget(DrawTarget *targetA, DrawTarget *targetB)
michael@0 451 {
michael@0 452 RefPtr<DrawTarget> newTarget =
michael@0 453 new DrawTargetDual(targetA, targetB);
michael@0 454
michael@0 455 RefPtr<DrawTarget> retVal = newTarget;
michael@0 456
michael@0 457 if (mRecorder) {
michael@0 458 retVal = new DrawTargetRecording(mRecorder, retVal);
michael@0 459 }
michael@0 460
michael@0 461 return retVal;
michael@0 462 }
michael@0 463
michael@0 464
michael@0 465 #ifdef WIN32
michael@0 466 TemporaryRef<DrawTarget>
michael@0 467 Factory::CreateDrawTargetForD3D10Texture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat)
michael@0 468 {
michael@0 469 RefPtr<DrawTargetD2D> newTarget;
michael@0 470
michael@0 471 newTarget = new DrawTargetD2D();
michael@0 472 if (newTarget->Init(aTexture, aFormat)) {
michael@0 473 RefPtr<DrawTarget> retVal = newTarget;
michael@0 474
michael@0 475 if (mRecorder) {
michael@0 476 retVal = new DrawTargetRecording(mRecorder, retVal, true);
michael@0 477 }
michael@0 478
michael@0 479 return retVal;
michael@0 480 }
michael@0 481
michael@0 482 gfxWarning() << "Failed to create draw target for D3D10 texture.";
michael@0 483
michael@0 484 // Failed
michael@0 485 return nullptr;
michael@0 486 }
michael@0 487
michael@0 488 TemporaryRef<DrawTarget>
michael@0 489 Factory::CreateDualDrawTargetForD3D10Textures(ID3D10Texture2D *aTextureA,
michael@0 490 ID3D10Texture2D *aTextureB,
michael@0 491 SurfaceFormat aFormat)
michael@0 492 {
michael@0 493 RefPtr<DrawTargetD2D> newTargetA;
michael@0 494 RefPtr<DrawTargetD2D> newTargetB;
michael@0 495
michael@0 496 newTargetA = new DrawTargetD2D();
michael@0 497 if (!newTargetA->Init(aTextureA, aFormat)) {
michael@0 498 gfxWarning() << "Failed to create draw target for D3D10 texture.";
michael@0 499 return nullptr;
michael@0 500 }
michael@0 501
michael@0 502 newTargetB = new DrawTargetD2D();
michael@0 503 if (!newTargetB->Init(aTextureB, aFormat)) {
michael@0 504 gfxWarning() << "Failed to create draw target for D3D10 texture.";
michael@0 505 return nullptr;
michael@0 506 }
michael@0 507
michael@0 508 RefPtr<DrawTarget> newTarget =
michael@0 509 new DrawTargetDual(newTargetA, newTargetB);
michael@0 510
michael@0 511 RefPtr<DrawTarget> retVal = newTarget;
michael@0 512
michael@0 513 if (mRecorder) {
michael@0 514 retVal = new DrawTargetRecording(mRecorder, retVal);
michael@0 515 }
michael@0 516
michael@0 517 return retVal;
michael@0 518 }
michael@0 519
michael@0 520 void
michael@0 521 Factory::SetDirect3D10Device(ID3D10Device1 *aDevice)
michael@0 522 {
michael@0 523 // do not throw on failure; return error codes and disconnect the device
michael@0 524 // On Windows 8 error codes are the default, but on Windows 7 the
michael@0 525 // default is to throw (or perhaps only with some drivers?)
michael@0 526 aDevice->SetExceptionMode(0);
michael@0 527 mD3D10Device = aDevice;
michael@0 528 }
michael@0 529
michael@0 530 ID3D10Device1*
michael@0 531 Factory::GetDirect3D10Device()
michael@0 532 {
michael@0 533 #ifdef DEBUG
michael@0 534 UINT mode = mD3D10Device->GetExceptionMode();
michael@0 535 MOZ_ASSERT(0 == mode);
michael@0 536 #endif
michael@0 537 return mD3D10Device;
michael@0 538 }
michael@0 539
michael@0 540 #ifdef USE_D2D1_1
michael@0 541 void
michael@0 542 Factory::SetDirect3D11Device(ID3D11Device *aDevice)
michael@0 543 {
michael@0 544 mD3D11Device = aDevice;
michael@0 545
michael@0 546 RefPtr<ID2D1Factory1> factory = D2DFactory1();
michael@0 547
michael@0 548 RefPtr<IDXGIDevice> device;
michael@0 549 aDevice->QueryInterface((IDXGIDevice**)byRef(device));
michael@0 550 factory->CreateDevice(device, &mD2D1Device);
michael@0 551 }
michael@0 552
michael@0 553 ID3D11Device*
michael@0 554 Factory::GetDirect3D11Device()
michael@0 555 {
michael@0 556 return mD3D11Device;
michael@0 557 }
michael@0 558
michael@0 559 ID2D1Device*
michael@0 560 Factory::GetD2D1Device()
michael@0 561 {
michael@0 562 return mD2D1Device;
michael@0 563 }
michael@0 564 #endif
michael@0 565
michael@0 566 TemporaryRef<GlyphRenderingOptions>
michael@0 567 Factory::CreateDWriteGlyphRenderingOptions(IDWriteRenderingParams *aParams)
michael@0 568 {
michael@0 569 RefPtr<GlyphRenderingOptions> options =
michael@0 570 new GlyphRenderingOptionsDWrite(aParams);
michael@0 571
michael@0 572 return options;
michael@0 573 }
michael@0 574
michael@0 575 uint64_t
michael@0 576 Factory::GetD2DVRAMUsageDrawTarget()
michael@0 577 {
michael@0 578 return DrawTargetD2D::mVRAMUsageDT;
michael@0 579 }
michael@0 580
michael@0 581 uint64_t
michael@0 582 Factory::GetD2DVRAMUsageSourceSurface()
michael@0 583 {
michael@0 584 return DrawTargetD2D::mVRAMUsageSS;
michael@0 585 }
michael@0 586
michael@0 587 void
michael@0 588 Factory::D2DCleanup()
michael@0 589 {
michael@0 590 DrawTargetD2D::CleanupD2D();
michael@0 591 }
michael@0 592
michael@0 593 #endif // XP_WIN
michael@0 594
michael@0 595 #ifdef USE_SKIA_GPU
michael@0 596 TemporaryRef<DrawTarget>
michael@0 597 Factory::CreateDrawTargetSkiaWithGrContext(GrContext* aGrContext,
michael@0 598 const IntSize &aSize,
michael@0 599 SurfaceFormat aFormat)
michael@0 600 {
michael@0 601 RefPtr<DrawTarget> newTarget = new DrawTargetSkia();
michael@0 602 if (!newTarget->InitWithGrContext(aGrContext, aSize, aFormat)) {
michael@0 603 return nullptr;
michael@0 604 }
michael@0 605 return newTarget;
michael@0 606 }
michael@0 607
michael@0 608 #endif // USE_SKIA_GPU
michael@0 609
michael@0 610 void
michael@0 611 Factory::PurgeAllCaches()
michael@0 612 {
michael@0 613 }
michael@0 614
michael@0 615 #ifdef USE_SKIA_FREETYPE
michael@0 616 TemporaryRef<GlyphRenderingOptions>
michael@0 617 Factory::CreateCairoGlyphRenderingOptions(FontHinting aHinting, bool aAutoHinting)
michael@0 618 {
michael@0 619 RefPtr<GlyphRenderingOptionsCairo> options =
michael@0 620 new GlyphRenderingOptionsCairo();
michael@0 621
michael@0 622 options->SetHinting(aHinting);
michael@0 623 options->SetAutoHinting(aAutoHinting);
michael@0 624 return options;
michael@0 625 }
michael@0 626 #endif
michael@0 627
michael@0 628 TemporaryRef<DrawTarget>
michael@0 629 Factory::CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat)
michael@0 630 {
michael@0 631 RefPtr<DrawTarget> retVal;
michael@0 632
michael@0 633 #ifdef USE_CAIRO
michael@0 634 RefPtr<DrawTargetCairo> newTarget = new DrawTargetCairo();
michael@0 635
michael@0 636 if (newTarget->Init(aSurface, aSize, aFormat)) {
michael@0 637 retVal = newTarget;
michael@0 638 }
michael@0 639
michael@0 640 if (mRecorder && retVal) {
michael@0 641 RefPtr<DrawTarget> recordDT = new DrawTargetRecording(mRecorder, retVal, true);
michael@0 642 return recordDT;
michael@0 643 }
michael@0 644 #endif
michael@0 645 return retVal;
michael@0 646 }
michael@0 647
michael@0 648 #ifdef XP_MACOSX
michael@0 649 TemporaryRef<DrawTarget>
michael@0 650 Factory::CreateDrawTargetForCairoCGContext(CGContextRef cg, const IntSize& aSize)
michael@0 651 {
michael@0 652 RefPtr<DrawTarget> retVal;
michael@0 653
michael@0 654 RefPtr<DrawTargetCG> newTarget = new DrawTargetCG();
michael@0 655
michael@0 656 if (newTarget->Init(cg, aSize)) {
michael@0 657 retVal = newTarget;
michael@0 658 }
michael@0 659
michael@0 660 if (mRecorder && retVal) {
michael@0 661 RefPtr<DrawTarget> recordDT = new DrawTargetRecording(mRecorder, retVal);
michael@0 662 return recordDT;
michael@0 663 }
michael@0 664 return retVal;
michael@0 665 }
michael@0 666 #endif
michael@0 667
michael@0 668 TemporaryRef<DataSourceSurface>
michael@0 669 Factory::CreateWrappingDataSourceSurface(uint8_t *aData, int32_t aStride,
michael@0 670 const IntSize &aSize,
michael@0 671 SurfaceFormat aFormat)
michael@0 672 {
michael@0 673 if (aSize.width <= 0 || aSize.height <= 0) {
michael@0 674 return nullptr;
michael@0 675 }
michael@0 676
michael@0 677 RefPtr<SourceSurfaceRawData> newSurf = new SourceSurfaceRawData();
michael@0 678
michael@0 679 if (newSurf->InitWrappingData(aData, aSize, aStride, aFormat, false)) {
michael@0 680 return newSurf;
michael@0 681 }
michael@0 682
michael@0 683 return nullptr;
michael@0 684 }
michael@0 685
michael@0 686 TemporaryRef<DataSourceSurface>
michael@0 687 Factory::CreateDataSourceSurface(const IntSize &aSize,
michael@0 688 SurfaceFormat aFormat)
michael@0 689 {
michael@0 690 if (!CheckSurfaceSize(aSize)) {
michael@0 691 return nullptr;
michael@0 692 }
michael@0 693
michael@0 694 RefPtr<SourceSurfaceAlignedRawData> newSurf = new SourceSurfaceAlignedRawData();
michael@0 695 if (newSurf->Init(aSize, aFormat)) {
michael@0 696 return newSurf;
michael@0 697 }
michael@0 698
michael@0 699 return nullptr;
michael@0 700 }
michael@0 701
michael@0 702 TemporaryRef<DataSourceSurface>
michael@0 703 Factory::CreateDataSourceSurfaceWithStride(const IntSize &aSize,
michael@0 704 SurfaceFormat aFormat,
michael@0 705 int32_t aStride)
michael@0 706 {
michael@0 707 if (aStride < aSize.width * BytesPerPixel(aFormat)) {
michael@0 708 return nullptr;
michael@0 709 }
michael@0 710
michael@0 711 RefPtr<SourceSurfaceAlignedRawData> newSurf = new SourceSurfaceAlignedRawData();
michael@0 712 if (newSurf->InitWithStride(aSize, aFormat, aStride)) {
michael@0 713 return newSurf;
michael@0 714 }
michael@0 715
michael@0 716 return nullptr;
michael@0 717 }
michael@0 718
michael@0 719 TemporaryRef<DrawEventRecorder>
michael@0 720 Factory::CreateEventRecorderForFile(const char *aFilename)
michael@0 721 {
michael@0 722 return new DrawEventRecorderFile(aFilename);
michael@0 723 }
michael@0 724
michael@0 725 void
michael@0 726 Factory::SetGlobalEventRecorder(DrawEventRecorder *aRecorder)
michael@0 727 {
michael@0 728 mRecorder = aRecorder;
michael@0 729 }
michael@0 730
michael@0 731 }
michael@0 732 }

mercurial