mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
c7dc12e90f
- Bug 1251253 - prevent null pointer dereference of |aContext| in CacheStorageService::DoomStorageEntries. r=mayhemer (35b449c612)
- Bug 1260498 - Make test_rel_preconnect work in e10s mode. r=mcmanus (e6823ce4c4)
- Bug 1016628 - Add prefetch abilities to the predictor. r=mayhemer (53ab180c97)
- Bug 1258482 - FileList should contain only Files, not Directories, r=smaug (ff78125454)
- Bug 1258694 - Implement Directory::GetFiles(), r=smaug (305784524e)
- Bug 1263992 - patch 1 - Remove DirectoryType enum, r=smaug (89e1a59041)
- Bug 1263992 - patch 2 - Support the creation of directories from FileSystemTasks, r=smaug (c569092cef)
- Bug 1243586 - Implement Upgrade-Insecure-Requests HTTP Request Header Field. r=rbarnes (4b8a84c656)
- Bug 1262572 - http 0.9 telemetry. r=hurley (6006881336)
- Bug 587177 - Update all comments before SetOriginalURI to reflect reality, r=mcmanus (b2fedb0728)
- Bug 1261632 - Assert that OnStopRequest is called only once. r=michal (c35b1922b9)
- Bug 1232422 - Convert 5 tests within netwerk/test to use AsyncOpen2 (r=mcmanus) (4af8d43814)
- Bug 831450 - No Range Requests against weak Etag r=mayhemer (9b4a159e1e)
- Bug 1214277 - Avoid bypassing opening a cache entry for possibly intercepted channels; r=mcmanus (c5b0de6990)
- partial apply Bug 1234369 - Convert 25 tests within netwerk/test to use AsyncOpen2 (1b81d5a303)
- Bug 299031 - heuristic cache rule for 410 should be longer r=mayhemer (848834fc31)
- Bug 1121447 - trust cache less for error codes r=mayhemer (0424fec819)
- Bug 1125916 - Check whether loadInfo and loadContext match. r=sicking, r=jduell (6740850922)
- Bug 1258778 - Purge the skia glyph cache when receiving a low memory notice. r=erahm (633c60b0c6)
- Bug 1125916 - Add SEC_FORCE_PRIVATE_BROWSING to LoadInfo. r=sicking, r=jduell (10b5a1cacb)
- Bug 1105556 - test fixes. r=sicking, ckerschb (845d0dbd65)
- Bug 1258481 - Use RegionBuilder for nsRegion IPC. r=jrmuizel (616c279297)
- Bug 1014691 - Fix an include-what-you-use error in TestCompositor.cpp. r=kats (2797f83f1d)
- Bug 1256408 - Add graphics microbenchmarking. r=mstange (49b11b051b)
- Bug 1258481 - Add a RegionBuilder for accumulating rects. r=jrmuizel (acd79192db)
- Track whether or not remote layers have acknowledged compositor changes. (bug 1256517 part 1, r=mattwoodrow) (e3cc77ed41)
- Move compositable field out of individual compositable ops. (bug 1256517 part 2, r=mattwoodrow) (1d4a063df3)
- Bug 1241058: Assure several operations properly operate on the current group target. r=jrmuizel (6119e2b4db)
- Bug 1247700: Avoid crash from invalid fonts. r=bas (c4c2799b94)
- Bug 1242421 - remove useless null check. r=roc@ocallahan.org (44faf6556d)
- Add instrumentation for when content processes fail to acquire D3D11 devices. (bug 1247539, r=milan) (bd9265d78e)
- Make access to gfxWindowsPlatform D3D11 devices thread-safe. (bug 1258174, r=bas) (032e74b163)
- Disable device access on textures created against stale layers. (bug 1256517 part 3, r=nical) (ffcebbdee6)
- Block compositable updates from stale layers. (bug 1256517 part 4, r=mattwoodrow,nical) (fc83339f2d)
- Fix build bustage for bug 1256517 r=broken tree (3952871373)
- Bug 1256678 - Replace DrawTargetCairo::FillGlyphs crashes with other crashes - r=bobowen (b7245ba436)
- Bug 1120485. Log CloseHandle error reason during MessageChannel shutdown failure. r=milan (2f81d9c2aa)
- Bug 1242448 - Ensure the tile pool does not hold textures during shutdown. r=edwin (d31c304258)
- Bug 1258851 - Propagate the isScrollbarContainer layer flag to the compositor. r=mattwoodrow (b9906d7557)
- Bug 1260391: Transfer |CompositableOperation| in |AsyncChildMessageData|, r=dvander (1def34c5f8)
- Bug 1252324 - add DrawTarget API for 3D transforms for use in layers. r=jrmuizel (bc80529422)
- Bug 1255342 - implement DrawTargetCairo::LockBits for Cairo Win32 surfaces. r=sotaro (6f5661691b)
- Bug 1263480 - Don't let cairo go into an error state when DrawSurface is called with an empty destination rectangle. r=lsalzman (4300940101)
- Bug 1251241 - return from DrawTargetCairo::FillGlyphs if |aFont| is ullptr. r=roc (bb92f95ccd)
- Bug 1255320 - Create DrawTarget with DIB as similar DrawTarget r=jrmuizel (03f1da030d)
- Bug 1215265 - Put shutting down gfx ipdl protocols for child processes behind a pref. r=sotaro (aa781b37f9)
- Bug 1262898: Keep the GeckoChildProcessHost alive for the lifetime of the CompositorBridge and ImageBridge parent actors. r=jimm r=nical (dcca3b54e1)
- Bug 1251619: Remove unused gfxPlatform::CreateDrawTargetForUpdateSurface r=mchang (b29565995e)
- Bug 1255973 - Remove redundant overrides from gfxPlatform subclasses. r=jfkthame (d45f8a6640)
- Bug 1259466. Rename layers.offmainthreadcomposition.enabled. r=milan We would rather people not use this pref. (f362da1bd3)
- Bug 881609: Call InitLayersAccelerationPrefs only once. r=nrc (faed10a0d4)
- Bug 1209780. Mark some DrawResult's as unused in layout/svg. r=seth (48192d6b34)
- Bug 1251115 - Fix incorrect rendering result while mask path is not resolvable; r=mstange (a52b478fdf)
- Bug 1228354 - Part1 - Support luminance mask mode. r=mstange r=bas (b03abbe8a6)
- Bug 1228354 - Part2. Add test case for mask-mode. r=heycam (6bea36a70c)
- Bug 1259802: Add type replacement annotations to simplify rust binding generation for nsStyleStruct.h, r=bholley (48c13e62f2)
- Bug 1261754 - Part 1: Improve static assertions for style struct bits. r=dholbert (2ce6d994a5)
- Bug 1261552 - Reimplement default placement-new for style structs. r=heycam (db9d7782e2)
- Bug 1261552 - Introduce StaticPresData and hoist some shared functionality into it. r=heycam (adf2e16b4d)
- Bug 1226627 - Truncate the result in ZoomText/UnZoomText rather than rounding it for better performance. r=roc (f1d1084ba1)
- Bug 1247777 - Part1: parse and compute -webkit-text-fill-color property. r=heycam (fc4161355c)
- Bug 1247777 - Part2: implement -webkit-text-fill-color rendering. r=jfkthame (0f30da9c5b)
- Bug 1247777 - Part3: reftests for -webkit-text-fill-color. r=jfkthame Add this test into web-platform-tests. (02e41db8cc)
- Bug 1043461 - Followup to ensure we still test custom property position when the UA style sheet doesn't have custom properties in it. r=dholbert (48df73d684)
- Bug 1247777 - Part4.1: replace windows-style line endings with unix-style line endings. r=bz (be8ba60960)
- Bug 1247777 - Part4.2: add compatible webkit prefixed properties in CSS properties ordering check test. r=bz (7b78825e14)
- Bug 1261552 - Introduce StyleStructContext, and make all style struct constructors take it. r=heycam (65b3966841)
- Bug 1258017 - Use an nsCOMPtr to hold onto the nsIStyleRule. r=dbaron (e88d7e368f)
- Bug 1258017 - Use a RefPtr to hold onto the parent style context. r=dbaron (6a7289ca43)
- Bug 1258017 - Redesign and simplify rule tree GC. r=dbaron (3bf60a9b04)
- Bug 1253149 - Remove the #ifdef __cplusplus bits from ServoBindings.h. r=SimonSapin (bf2b18a470)
- Bug 1251496 - Forward stylesheet management to RawServoStyleSet. r=heycam (0a3aa90b2d)
- Bug 1260310 - Generalize nsStyleContext to support resolving styles from either nsRuleNode or ServoComputedValues. r=heycam (82b6d5d008)
- Bug 1258017 - Cleanup fixes for trunk. r=me (674a65815a)
- Bug 1236400 part 1: Add internal enum values to represent "display: -webkit-box" & "display: -webkit-inline-box". r=mats (509c94da15)
- Bug 1236400 part 2: Extend NeedsAnonFlexOrGridItem() & related code to wrap all inline-level -webkit-box children in an anonymous flex item. r=mats (dc11b9b09f)
- Bug 1236400 part 3: If webkit prefix support is enabled, skip CSS Parser code that converts "display: -webkit-box" directly to "display: flex". r=mats (e09b459124)
- Bug 1236400 part 4: Add reftests to test how non-block-level content gets wrapped inside a -webkit-box. (no review) (46e4d8cb07)
- Bug 1261754 - Part 2: Make quotes computed values shareable between different structs. r=dholbert (a78e43b706)
- Bug 1261754 - Part 3: Move quotes from nsStyleQuotes to nsStyleList and delete nsStyleQuotes. r=dholbert (fdcd9aaa3f)
- Bug 1209273 - Part 1: Support for adjust-color CSS property. r=dbaron (818a7fe0ff)
- Bug 1209273 - Part 2: Force printing background if color-adjust: exact. r=dbaron (ffd52c0dbc)
- Bug 1261754 - Part 4: Move image-rendering from nsStyleSVG to nsStyleVisibility. r=dholbert (ee8372fb94)
- Bug 1261754 - Part 5: Move text-rendering from nsStyleSVG to nsStyleText. r=dholbert (c13a11313d)
- Bug 1261754 - Part 6: Move vertical-align from nsStyleTextReset to nsStyleDisplay. r=dholbert (d374b3700b)
- Bug 1261754 - Part 7: Move pointer-events from nsStyleVisibility to nsStyleUserInterface. r=dholbert (8693251243)
- Bug 1261754 - Part 8: Move box-shadow from nsStyleBorder to a new nsStyleEffects struct. r=dholbert (8263476827)
- Bug 1261754 - Part 9: Move clip from nsStyleDisplay to nsStyleEffects. r=dholbert (5418597309)
- Bug 1261754 - Part 10: Move mix-blend-mode from nsStyleDisplay to nsStyleEffects. r=dholbert (ebae613929)
- Bug 1261754 - Part 11: Move opacity from nsStyleDisplay to nsStyleEffects. r=dholbert (589292af44)
- Bug 1187851 patch 6 - Make dynamic changes to filter change fixed position containing block for descendants. r=roc (003a3aa6ce)
- Bug 1261754 - Part 12: Move filter from nsStyleSVGReset to nsStyleEffects. r=dholbert (78d87914f9)
- Bug 1259513: Make gfxContext constructor private, use a utility function that can return nullptr. r=bas,lsalzman (43df6e429f)
- Bug 1259785: Do a proper flush when taking a snapshot so our dependent targets and command lists get appropriately cleared. r=jrmuizel (9f7372cce1)
- Bug 1251431 - Part 1: Allow usage of an A8 source pattern to MaskSurface for D2D 1.1 Moz2D backend. r=jwatt (632eb6d2da)
- Bug 1251431 - Part 2: Do not apply the device transform when drawing to an already intermediate surface. r=jwatt (3a24f4a5c6)
- Bug 1251431 - GCC compilation fixup. (2356f0a58c)
- Bug 1238328: Purge stored command lists by calling EndDraw/BeginDraw on a regular basis when they're used. r=jrmuizel (33f47b281f)
- Bug 1246641: Also execute an occasional EndDraw for CommandLists used by non-operator OVER drawing. r=jrmuizel (b3e03ad111)
- Bug 1258168: Push ClearType compatible clipping layers when the last pushed layer was marked as opaque. r=jrmuizel (bd069ad7b6)
- Bug 1264736: Crash sooner if we can't get a valid command list, at least in nightly/aurora. r=bas (fb4bb56815)
- Bug 1255438 - create nsI{Mutable,}Array directly; r=keeler (1b802b23b7)
- Bug 1255438 - fix OS X warning bustage and reopen this CLOSED TREE; r=me (07a05910a6)
- bug 1197314: Remove PR_snprintf calls in security/manager/ssl/ r=keeler (f2271aad87)
- Bug 1258298 - Switch more Scoped.h templates in PSM to UniquePtr equivalents. r=keeler (2ee1a85d8e)
- Bug 1191414 - gather telemetry on usage of <keygen>. r=keeler,r=vladan (150bad38a1)
- Bug 1260644 - Use UniquePLArenaPool to manage PLArenaPools in PSM. r=keeler (9e8ad9c0d4)
- Bug 1247250 - Enable TLS 1.3 anti-downgrade on non-secure fallback. r=keeler (7a950b427a)
- Bug 1215796 - Remove the static fallback whitelist. r=keeler (fa55b5920b)
- bug 1254667 - change certificate verification SHA1 policy to "allow or locally-installed roots" r=jcj (5d0bb9e8b1)
- bug 1245280 - add policy mechanism to optionally enforce BRs for falling back to subject CN r=Cykesiopka,mgoodwin (ecd4f2180a)
- Bug 1254653 - Add telemetry to measure how often we encounter EV certificates r=keeler (9da287b490)
- Bug 1259909 - Obviate char PORT_Free() calls in PSM. r=keeler (b7ba2a47da)
- Bug 1252882 - Add a Content Signature Service r=keeler,r=franziskus,r=Cykesiopka (8b806022a0)
- Bug 1255784 - u2f tests should use SpecialPowers.pushPrefEnv, r=jjones (839a58476f)
- Bug 1244960 - Complete FIDO u2f NSSToken (Part 1). r=keeler, r=baku (3d64aa2b7c)
- Bug 1244960 - FIDO u2f NSSToken (Part 2): Use Attestation Certificates. r=keeler (aee3ffc830)
- Bug 1244960 - FIDO u2f NSSToken (Part 3): Review updates. r=keeler (b2f81c2b72)
- Bug 1244960 - FIDO u2f NSSToken (Part 4): Correct FacetID base algorithm. r=keeler (9e70506580)
- Bug 1244960 - FIDO u2f NSSToken (Part 5): Review updates. r=keeler (62a28f2502)
- Bug 1231643 - Part 1. Create skia-A8-surface for mask composition when backendtype of the source DrawTarget is CG; r=mstange (dd03d86f55)
- Bug 1244598 - Move resource files of w3c-css/masking into ./support subdir. r=dbaron (4c9e789191)
- Bug 1243675 - Part 1. Add mask-image property reftest. r=dbaron (18e5dfa90b)
- Bug 1243675 - Part 2. Add mask-clip property reftest. r=dbaron (ddf834d408)
- Bug 1243675 - Part 3. Add mask-position property reftest. r=dbaron (68cae7c7e6)
- Bug 1243675 - Part 4. Add mask-repeat property reftest. r=dbaron (0a3ed45377)
- Bug 1243675 - Part 5. Add mask-origin property reftest. r=dbaron (f5785145a7)
- Bug 1243675 - Part 6. Add mask-size property reftest. r=dbaron (1ab2040973)
- Bug 1231643 - Part 2. Enable mask-composite reftest; r=dbaron (8c3b863d97)
- Bug 1263622 - Fixed nsNSSComponent.cpp compilation on mingw. r=dkeeler,ted (0e651c0211)
- Bug 1266249 - Remove mHasCachedOutline. r=dbaron (c46459acf2)
- Bug 1235634 - Construct nsNSSShutdownList::singleton lazily on first use r=keeler (1b53753c2e)
- Bug 1262645 - Address misc issues with nsGetUserCertChoice(). r=keeler (ec675be29a)
- Bug 1238001 - Allow TLS info to be updated on renegotiation, r=keeler (a2ec0c8a07)
- Bug 1201437 - Add new WebProgress state flag for user-overridden cert. r=keeler (0b9edbc8d8)
- Bug 1201437 - Make cert override tests check for STATE_CERT_USER_OVERRIDDEN. r=keeler (5246515084)
- bug 1261936 - stop using the subject common name in certificate verification error messages r=Cykesiopka (982cf43a11)
- bug 1230234 - fix a leak in client auth certificate handling r=Cykesiopka (6e83f81218)
- Bug 1260643 - Convert most uses of ScopedCERTCertificate in PSM to UniqueCERTCertificate. r=keeler (806b895c41)
- Bug 1207137 - Set a security state flag when weak crypto override is needed. r=keeler Bug 1254306 - Do not check the fallback limit version for the RC4 fallback. r=keeler (8b5cb7101f)
- Bug 1253010 - part 3 - create all nsIDateTimeFormat instances directly; r=smontagu (c1aa5d1d62)
- Bug 1260310 - Create servo style contexts from ServoStyleSet. r=heycam (05f876eb13)
- Bug 759568 - Part 1. Parse background-clip:text; r=dholbert r=heycam (d013b8fd84)
- Bug 1251995 part 6 - Use struct to pass params for nsTextFrame::PainText* functions. r=jfkthame (3b9c163eab)
- Bug 759568 - Part 2. Render background-clip:text; r=jfkthame (e534e048bf)
- Bug 759568 - Part 4. mochitest for background-clip:text; r=heycom (3e548ebf99)
- Bug 759568 - Part 5. reftest for background-clip:text; r=dbaron (43d2915305)
- Bug 759568 - Part 6. Remove unused nsDisplayList::mVisibleRect; r=jfkthame (960a85de40)
- Bug 1264910 - Simplify pref callback register/unregister in nsLayoutUtils. r=dholbert (f50219f117)
- Bug 1097499 part 1 - Control support of 'text-combine-upright: digits' via a separate pref. r=heycam (37df36e815)
- Bug 1261062 - When constraining the displayport by the max texture size, maintain the relative distribution of the margins. r=dvander (9a9423bdf1)
- Bug 1246290 - Add a pref to allow disabling APZ on documents which have scroll-linked effects. r=botond (781b63c578)
- Bug 1263347 - When checking if displayport changes should schedule a paint, make sure to use the proper displayport. r=mstange (998f59843e)
- Bug 1097499 part 15 - Add reftests for text-combine-upright. r=jfkthame (843bea00bc)
- Bug 1097499 followup - Fix metadata of tests submitted to w3c. DONTBUILD (e671b5b38b)
- Bug 1097499 followup 2 - Fix metadata of tests submitted to w3c. DONTBUILD (abf0895450)
- Bug 1097499 part 2 - Add a macro to simplify usage of nsStyleContext::GetUniqueStyleData. r=heycam (10486f1f24)
- Bug 1097499 part 3 - Add a separate anonbox for text nodes. r=heycam (7dd4347215)
- Bug 1097499 part 4 - Adjust computed value of writing-mode on text frames when text-combine-upright is used. r=heycam (c193f14b27)
- Bug 1097499 part 5 - Layout text combine upright. r=jfkthame (c21422930b)
- Bug 1097499 part 6 - Inherit move direction from parent for horizontal-in-vertical text. r=jfkthame (cf436b8494)
- Bug 1097499 part 7 - Add reverse function of GetFullWidth. r=emk (32d02e7437)
- Bug 1097499 part 8 - Move CountGraphemeClusters to mozilla::unicode. r=emk (e2b8942e53)
- Bug 1156588 - Add crashtest. (237adb0604)
- Bug 1234622. Tweak how nsDocumentViewer::FindContainerView finds the parent presshell. r=bz (d1e76ae2e9)
- Bug 1245978 part 1: Make nsDocumentViewer::CreateStyleSet directly return the thing it creates. r=heycam (ede16260a4)
- Bug 1245978 part 2: Drop redundant 'virtual' keyword from NS_DECL_NSIDOCUMENTVIEWERPRINT macro (which already includes 'override' keyword). r=heycam (42b8962e4f)
- Bug 1183879 - Soften "non-subdocument frame" warning to also allow dummy nsFrames, which exist while subdocument is loading. r=dholbert (6ebcb53421)
- Bug 1259246. Move nsIPresShell::GetRealPrimaryFrameFor to nsLayoutUtils::GetRealPrimaryFrameFor. r=dholbert (d3efd2f03a)
- Bug 645647 part 1 - Don't let empty bullet frames block suppressing white-space in intrinsic size calculations. r=dholbert (2ce0a86bfb)
- Bug 645647 part 2 - Reftests. (496e491990)
- Bug 645647 part 3 - Remove unused trailingTextFrame member. r=dholbert (bd26ea25e6)
- Bug 645647 part 4 - Add an 'm' prefix to some members to follow our naming conventions. r=dholbert (fe3c5240c9)
- Bug 1097499 part 9 - Transform full-width characters to non-full-width correspondents for combined text. r=jfkthame (5b1eafe2a7)
- Bug 1097499 part 10 - Add fwid/hwid/twid/qwid font feature support to gfx. r=jfkthame (682698dd38)
- Bug 1097499 part 11 - Set width variant for text-combined frame. r=jfkthame (937f61e0e9)
- Bug 1097499 part 12 - Handle spacing sensibly for text-combine-upright. r=jfkthame (9ae1ab2941)
- Bug 1220438 - Correct baseline offset computation of text decoration for vertical-rl. r=jfkthame (10ad32d702)
- Bug 1258636 part 1 - Use structs to pass params for decoration-related functions in nsCSSRendering. r=jfkthame (deef7071f1)
- Bug 1258636 part 2 - Use struct to pass params for nsTextFrame::PaintDecorationLine. r=jfkthame (df5bde2547)
- Bug 1229743 part 1 - Simplify text decoration handling code with lambda function and range-based for loop. r=jfkthame (51cd3ea4ca)
- Bug 1229743 part 2 - Fix up decoration rect computation for vertical-rl and sideways-lr. r=jfkthame (0113279f53)
- Bug 1251995 part 7 - Use struct to pass params for nsTextFrame::Paint*Shadow functions. r=jfkthame (e81ba231aa)
- Bug 759568 - Part 3. Render text-selection beneath background image; r=jfkthame (e6757762ff)
- Bug 1097499 part 13 - Draw decoration line properly for text-combine-upright. r=jfkthame (8f4be7f987)
- Bug 1264120. Remove usage of nsAutoPtr from gfx/src. r=jfkthame (6831454d8c)
- Bug 1119619 - Allow font-selection to fall back to an alternative face within the same family if the first-found face was not Regular, to handle cases where some styled faces have a reduced character set. r=m_kato (d8851b2877)
- Bug 1243226 - relax the limit on fontconfig generics. r=heycam, a=me (05df737d0e)
- Bug 1245811 - part 1 (based on patch by Andrew Comminos) - Replace gfxPlatformFontList::FindFamily with FindAndAddFamilies to allow for the possibility of the implementation returning multiple font families (e.g. when fontconfig has 'prefer' aliases). r=karlt (2bef9fafb0)
- Bug 1245811 - part 2 (based on patch by Andrew Comminos) - Let gfxFcPlatformFontList return multiple families for a given name once fontconfig substitutions have been applied. r=karlt (1ffb425a0e)
- Bug 1265452 - Remove use of nsAutoPtr from gfx/thebes. r=jrmuizel (d02c913ad5)
- Bug 1265459 - Replace uses of nsAutoPtr<gfxTextRun> with UniquePtr, and let MakeTextRun and similar methods return a UniquePtr. r=jrmuizel (da32e376b7)
- Bug 1097499 part 14 - Draw emphasis marks properly for text-combine-upright. r=jfkthame (c9115615c6)
- Bug 1097499 part 16 - Enable text-combine-upright by default. r=jfkthame (b616987f95)
- Bug 1261699 - preserve user fontconfig autohint settings in Cairo glyph rendering options. r=jfkthame (3e46dff5ff)
- Bug 1216001 - Fix a typo that eliminated a possible paint optimization. r=xidorn (6a350cadb7)
- Bug 1261568 - part1: take -webkit-text-fill-color into consideration while (d49cf427ab)
- Bug 1261568 - part2.1: update manifest before adding test. r=jgraham Bug 1261568 - part2.2: add reftest. r=jfkthame (ef3c22cfb4)
994 lines
34 KiB
C++
994 lines
34 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include <stdint.h> // for uint32_t
|
|
#include <stdlib.h> // for rand, RAND_MAX
|
|
#include <sys/types.h> // for int32_t
|
|
#include "BasicContainerLayer.h" // for BasicContainerLayer
|
|
#include "BasicLayersImpl.h" // for ToData, BasicReadbackLayer, etc
|
|
#include "GeckoProfiler.h" // for PROFILER_LABEL
|
|
#include "ImageContainer.h" // for ImageFactory
|
|
#include "Layers.h" // for Layer, ContainerLayer, etc
|
|
#include "ReadbackLayer.h" // for ReadbackLayer
|
|
#include "ReadbackProcessor.h" // for ReadbackProcessor
|
|
#include "RenderTrace.h" // for RenderTraceLayers, etc
|
|
#include "basic/BasicImplData.h" // for BasicImplData
|
|
#include "basic/BasicLayers.h" // for BasicLayerManager, etc
|
|
#include "gfxASurface.h" // for gfxASurface, etc
|
|
#include "gfxContext.h" // for gfxContext, etc
|
|
#include "gfxImageSurface.h" // for gfxImageSurface
|
|
#include "gfxMatrix.h" // for gfxMatrix
|
|
#include "gfxPlatform.h" // for gfxPlatform
|
|
#include "gfxPrefs.h" // for gfxPrefs
|
|
#include "gfxPoint.h" // for IntSize, gfxPoint
|
|
#include "gfxRect.h" // for gfxRect
|
|
#include "gfxUtils.h" // for gfxUtils
|
|
#include "gfx2DGlue.h" // for thebes --> moz2d transition
|
|
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
|
|
#include "mozilla/WidgetUtils.h" // for ScreenRotation
|
|
#include "mozilla/gfx/2D.h" // for DrawTarget
|
|
#include "mozilla/gfx/BasePoint.h" // for BasePoint
|
|
#include "mozilla/gfx/BaseRect.h" // for BaseRect
|
|
#include "mozilla/gfx/Matrix.h" // for Matrix
|
|
#include "mozilla/gfx/PathHelpers.h"
|
|
#include "mozilla/gfx/Rect.h" // for IntRect, Rect
|
|
#include "mozilla/layers/LayersTypes.h" // for BufferMode::BUFFER_NONE, etc
|
|
#include "mozilla/mozalloc.h" // for operator new
|
|
#include "nsAutoPtr.h" // for nsRefPtr
|
|
#include "nsCOMPtr.h" // for already_AddRefed
|
|
#include "nsDebug.h" // for NS_ASSERTION, etc
|
|
#include "nsISupportsImpl.h" // for gfxContext::Release, etc
|
|
#include "nsPoint.h" // for nsIntPoint
|
|
#include "nsRect.h" // for mozilla::gfx::IntRect
|
|
#include "nsRegion.h" // for nsIntRegion, etc
|
|
#include "nsTArray.h" // for AutoTArray
|
|
class nsIWidget;
|
|
|
|
namespace mozilla {
|
|
namespace layers {
|
|
|
|
using namespace mozilla::gfx;
|
|
|
|
/**
|
|
* Clips to the smallest device-pixel-aligned rectangle containing aRect
|
|
* in user space.
|
|
* Returns true if the clip is "perfect", i.e. we actually clipped exactly to
|
|
* aRect.
|
|
*/
|
|
static bool
|
|
ClipToContain(gfxContext* aContext, const IntRect& aRect)
|
|
{
|
|
gfxRect userRect(aRect.x, aRect.y, aRect.width, aRect.height);
|
|
gfxRect deviceRect = aContext->UserToDevice(userRect);
|
|
deviceRect.RoundOut();
|
|
|
|
gfxMatrix currentMatrix = aContext->CurrentMatrix();
|
|
aContext->SetMatrix(gfxMatrix());
|
|
aContext->NewPath();
|
|
aContext->Rectangle(deviceRect);
|
|
aContext->Clip();
|
|
aContext->SetMatrix(currentMatrix);
|
|
|
|
return aContext->DeviceToUser(deviceRect).IsEqualInterior(userRect);
|
|
}
|
|
|
|
BasicLayerManager::PushedGroup
|
|
BasicLayerManager::PushGroupForLayer(gfxContext* aContext, Layer* aLayer, const nsIntRegion& aRegion)
|
|
{
|
|
PushedGroup group;
|
|
|
|
group.mVisibleRegion = aRegion;
|
|
group.mFinalTarget = aContext;
|
|
group.mOperator = GetEffectiveOperator(aLayer);
|
|
group.mOpacity = aLayer->GetEffectiveOpacity();
|
|
|
|
// If we need to call PushGroup, we should clip to the smallest possible
|
|
// area first to minimize the size of the temporary surface.
|
|
bool didCompleteClip = ClipToContain(aContext, aRegion.GetBounds());
|
|
|
|
bool canPushGroup = group.mOperator == CompositionOp::OP_OVER ||
|
|
(group.mOperator == CompositionOp::OP_SOURCE && (aLayer->CanUseOpaqueSurface() || aLayer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA));
|
|
|
|
if (!canPushGroup) {
|
|
aContext->Save();
|
|
gfxUtils::ClipToRegion(group.mFinalTarget, group.mVisibleRegion);
|
|
|
|
// PushGroup/PopGroup do not support non operator over.
|
|
gfxMatrix oldMat = aContext->CurrentMatrix();
|
|
aContext->SetMatrix(gfxMatrix());
|
|
gfxRect rect = aContext->GetClipExtents();
|
|
aContext->SetMatrix(oldMat);
|
|
rect.RoundOut();
|
|
IntRect surfRect;
|
|
ToRect(rect).ToIntRect(&surfRect);
|
|
|
|
if (!surfRect.IsEmpty()) {
|
|
RefPtr<DrawTarget> dt = aContext->GetDrawTarget()->CreateSimilarDrawTarget(surfRect.Size(), SurfaceFormat::B8G8R8A8);
|
|
|
|
RefPtr<gfxContext> ctx = gfxContext::ForDrawTarget(dt, ToRect(rect).TopLeft());
|
|
if (!ctx) {
|
|
gfxDevCrash(LogReason::InvalidContext) << "BasicLayerManager context problem " << gfx::hexa(dt);
|
|
return group;
|
|
}
|
|
ctx->SetMatrix(oldMat);
|
|
|
|
group.mGroupOffset = surfRect.TopLeft();
|
|
group.mGroupTarget = ctx;
|
|
|
|
group.mMaskSurface = GetMaskForLayer(aLayer, &group.mMaskTransform);
|
|
return group;
|
|
}
|
|
aContext->Restore();
|
|
}
|
|
|
|
Matrix maskTransform;
|
|
RefPtr<SourceSurface> maskSurf = GetMaskForLayer(aLayer, &maskTransform);
|
|
|
|
if (maskSurf) {
|
|
// The returned transform will transform the mask to device space on the
|
|
// destination. Since the User->Device space transform will be applied
|
|
// to the mask by PopGroupAndBlend we need to adjust the transform to
|
|
// transform the mask to user space.
|
|
Matrix currentTransform = ToMatrix(group.mFinalTarget->CurrentMatrix());
|
|
currentTransform.Invert();
|
|
maskTransform = maskTransform * currentTransform;
|
|
}
|
|
|
|
if (aLayer->CanUseOpaqueSurface() &&
|
|
((didCompleteClip && aRegion.GetNumRects() == 1) ||
|
|
!aContext->CurrentMatrix().HasNonIntegerTranslation())) {
|
|
// If the layer is opaque in its visible region we can push a gfxContentType::COLOR
|
|
// group. We need to make sure that only pixels inside the layer's visible
|
|
// region are copied back to the destination. Remember if we've already
|
|
// clipped precisely to the visible region.
|
|
group.mNeedsClipToVisibleRegion = !didCompleteClip || aRegion.GetNumRects() > 1;
|
|
if (group.mNeedsClipToVisibleRegion) {
|
|
group.mFinalTarget->Save();
|
|
gfxUtils::ClipToRegion(group.mFinalTarget, group.mVisibleRegion);
|
|
}
|
|
|
|
aContext->PushGroupForBlendBack(gfxContentType::COLOR, group.mOpacity, maskSurf, maskTransform);
|
|
} else {
|
|
if (aLayer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA) {
|
|
aContext->PushGroupAndCopyBackground(gfxContentType::COLOR_ALPHA, group.mOpacity, maskSurf, maskTransform);
|
|
} else {
|
|
aContext->PushGroupForBlendBack(gfxContentType::COLOR_ALPHA, group.mOpacity, maskSurf, maskTransform);
|
|
}
|
|
}
|
|
|
|
group.mGroupTarget = group.mFinalTarget;
|
|
return group;
|
|
}
|
|
|
|
void
|
|
BasicLayerManager::PopGroupForLayer(PushedGroup &group)
|
|
{
|
|
if (group.mFinalTarget == group.mGroupTarget) {
|
|
group.mFinalTarget->PopGroupAndBlend();
|
|
if (group.mNeedsClipToVisibleRegion) {
|
|
group.mFinalTarget->Restore();
|
|
}
|
|
return;
|
|
}
|
|
|
|
DrawTarget* dt = group.mFinalTarget->GetDrawTarget();
|
|
RefPtr<DrawTarget> sourceDT = group.mGroupTarget->GetDrawTarget();
|
|
group.mGroupTarget = nullptr;
|
|
|
|
RefPtr<SourceSurface> src = sourceDT->Snapshot();
|
|
|
|
if (group.mMaskSurface) {
|
|
Point finalOffset = group.mFinalTarget->GetDeviceOffset();
|
|
dt->SetTransform(group.mMaskTransform * Matrix::Translation(-finalOffset));
|
|
Matrix surfTransform = group.mMaskTransform;
|
|
surfTransform.Invert();
|
|
dt->MaskSurface(SurfacePattern(src, ExtendMode::CLAMP, surfTransform *
|
|
Matrix::Translation(group.mGroupOffset.x, group.mGroupOffset.y)),
|
|
group.mMaskSurface, Point(0, 0), DrawOptions(group.mOpacity, group.mOperator));
|
|
} else {
|
|
// For now this is required since our group offset is in device space of the final target,
|
|
// context but that may still have its own device offset. Once PushGroup/PopGroup logic is
|
|
// migrated to DrawTargets this can go as gfxContext::GetDeviceOffset will essentially
|
|
// always become null.
|
|
dt->SetTransform(Matrix::Translation(-group.mFinalTarget->GetDeviceOffset()));
|
|
dt->DrawSurface(src, Rect(group.mGroupOffset.x, group.mGroupOffset.y, src->GetSize().width, src->GetSize().height),
|
|
Rect(0, 0, src->GetSize().width, src->GetSize().height), DrawSurfaceOptions(Filter::POINT), DrawOptions(group.mOpacity, group.mOperator));
|
|
}
|
|
|
|
if (group.mNeedsClipToVisibleRegion) {
|
|
dt->PopClip();
|
|
}
|
|
|
|
group.mFinalTarget->Restore();
|
|
}
|
|
|
|
static IntRect
|
|
ToInsideIntRect(const gfxRect& aRect)
|
|
{
|
|
gfxRect r = aRect;
|
|
r.RoundIn();
|
|
return IntRect(r.X(), r.Y(), r.Width(), r.Height());
|
|
}
|
|
|
|
// A context helper for BasicLayerManager::PaintLayer() that holds all the
|
|
// painting context together in a data structure so it can be easily passed
|
|
// around. It also uses ensures that the Transform and Opaque rect are restored
|
|
// to their former state on destruction.
|
|
|
|
class PaintLayerContext {
|
|
public:
|
|
PaintLayerContext(gfxContext* aTarget, Layer* aLayer,
|
|
LayerManager::DrawPaintedLayerCallback aCallback,
|
|
void* aCallbackData)
|
|
: mTarget(aTarget)
|
|
, mTargetMatrixSR(aTarget)
|
|
, mLayer(aLayer)
|
|
, mCallback(aCallback)
|
|
, mCallbackData(aCallbackData)
|
|
, mPushedOpaqueRect(false)
|
|
{}
|
|
|
|
~PaintLayerContext()
|
|
{
|
|
// Matrix is restored by mTargetMatrixSR
|
|
if (mPushedOpaqueRect)
|
|
{
|
|
ClearOpaqueRect();
|
|
}
|
|
}
|
|
|
|
// Gets the effective transform and returns true if it is a 2D
|
|
// transform.
|
|
bool Setup2DTransform()
|
|
{
|
|
// Will return an identity matrix for 3d transforms.
|
|
return mLayer->GetEffectiveTransformForBuffer().CanDraw2D(&mTransform);
|
|
}
|
|
|
|
// Applies the effective transform if it's 2D. If it's a 3D transform then
|
|
// it applies an identity.
|
|
void Apply2DTransform()
|
|
{
|
|
mTarget->SetMatrix(ThebesMatrix(mTransform));
|
|
}
|
|
|
|
// Set the opaque rect to match the bounds of the visible region.
|
|
void AnnotateOpaqueRect()
|
|
{
|
|
const nsIntRegion visibleRegion = mLayer->GetLocalVisibleRegion().ToUnknownRegion();
|
|
const IntRect& bounds = visibleRegion.GetBounds();
|
|
|
|
DrawTarget *dt = mTarget->GetDrawTarget();
|
|
const IntRect& targetOpaqueRect = dt->GetOpaqueRect();
|
|
|
|
// Try to annotate currentSurface with a region of pixels that have been
|
|
// (or will be) painted opaque, if no such region is currently set.
|
|
if (targetOpaqueRect.IsEmpty() && visibleRegion.GetNumRects() == 1 &&
|
|
(mLayer->GetContentFlags() & Layer::CONTENT_OPAQUE) &&
|
|
!mTransform.HasNonAxisAlignedTransform()) {
|
|
|
|
gfx::Rect opaqueRect = dt->GetTransform().TransformBounds(
|
|
gfx::Rect(bounds.x, bounds.y, bounds.width, bounds.height));
|
|
opaqueRect.RoundIn();
|
|
IntRect intOpaqueRect;
|
|
if (opaqueRect.ToIntRect(&intOpaqueRect)) {
|
|
mTarget->GetDrawTarget()->SetOpaqueRect(intOpaqueRect);
|
|
mPushedOpaqueRect = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Clear the Opaque rect. Although this doesn't really restore it to it's
|
|
// previous state it will happen on the exit path of the PaintLayer() so when
|
|
// painting is complete the opaque rect qill be clear.
|
|
void ClearOpaqueRect() {
|
|
mTarget->GetDrawTarget()->SetOpaqueRect(IntRect());
|
|
}
|
|
|
|
gfxContext* mTarget;
|
|
gfxContextMatrixAutoSaveRestore mTargetMatrixSR;
|
|
Layer* mLayer;
|
|
LayerManager::DrawPaintedLayerCallback mCallback;
|
|
void* mCallbackData;
|
|
Matrix mTransform;
|
|
bool mPushedOpaqueRect;
|
|
};
|
|
|
|
BasicLayerManager::BasicLayerManager(nsIWidget* aWidget)
|
|
: mPhase(PHASE_NONE)
|
|
, mWidget(aWidget)
|
|
, mDoubleBuffering(BufferMode::BUFFER_NONE)
|
|
, mType(BLM_WIDGET)
|
|
, mUsingDefaultTarget(false)
|
|
, mTransactionIncomplete(false)
|
|
, mCompositorMightResample(false)
|
|
{
|
|
MOZ_COUNT_CTOR(BasicLayerManager);
|
|
NS_ASSERTION(aWidget, "Must provide a widget");
|
|
}
|
|
|
|
BasicLayerManager::BasicLayerManager(BasicLayerManagerType aType)
|
|
: mPhase(PHASE_NONE)
|
|
, mWidget(nullptr)
|
|
, mDoubleBuffering(BufferMode::BUFFER_NONE)
|
|
, mType(aType)
|
|
, mUsingDefaultTarget(false)
|
|
, mTransactionIncomplete(false)
|
|
{
|
|
MOZ_COUNT_CTOR(BasicLayerManager);
|
|
MOZ_ASSERT(mType != BLM_WIDGET);
|
|
}
|
|
|
|
BasicLayerManager::~BasicLayerManager()
|
|
{
|
|
NS_ASSERTION(!InTransaction(), "Died during transaction?");
|
|
|
|
ClearCachedResources();
|
|
|
|
mRoot = nullptr;
|
|
|
|
MOZ_COUNT_DTOR(BasicLayerManager);
|
|
}
|
|
|
|
void
|
|
BasicLayerManager::SetDefaultTarget(gfxContext* aContext)
|
|
{
|
|
NS_ASSERTION(!InTransaction(),
|
|
"Must set default target outside transaction");
|
|
mDefaultTarget = aContext;
|
|
}
|
|
|
|
void
|
|
BasicLayerManager::SetDefaultTargetConfiguration(BufferMode aDoubleBuffering, ScreenRotation aRotation)
|
|
{
|
|
mDoubleBuffering = aDoubleBuffering;
|
|
}
|
|
|
|
void
|
|
BasicLayerManager::BeginTransaction()
|
|
{
|
|
mInTransaction = true;
|
|
mUsingDefaultTarget = true;
|
|
BeginTransactionWithTarget(mDefaultTarget);
|
|
}
|
|
|
|
void
|
|
BasicLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
|
|
{
|
|
mInTransaction = true;
|
|
|
|
#ifdef MOZ_LAYERS_HAVE_LOG
|
|
MOZ_LAYERS_LOG(("[----- BeginTransaction"));
|
|
Log();
|
|
#endif
|
|
|
|
NS_ASSERTION(!InTransaction(), "Nested transactions not allowed");
|
|
mPhase = PHASE_CONSTRUCTION;
|
|
mTarget = aTarget;
|
|
}
|
|
|
|
static void
|
|
TransformIntRect(IntRect& aRect, const Matrix& aMatrix,
|
|
IntRect (*aRoundMethod)(const gfxRect&))
|
|
{
|
|
Rect gr = Rect(aRect.x, aRect.y, aRect.width, aRect.height);
|
|
gr = aMatrix.TransformBounds(gr);
|
|
aRect = (*aRoundMethod)(ThebesRect(gr));
|
|
}
|
|
|
|
/**
|
|
* This function assumes that GetEffectiveTransform transforms
|
|
* all layers to the same coordinate system (the "root coordinate system").
|
|
* It can't be used as is by accelerated layers because of intermediate surfaces.
|
|
* This must set the hidden flag to true or false on *all* layers in the subtree.
|
|
* It also sets the operator for all layers to "OVER", and call
|
|
* SetDrawAtomically(false).
|
|
* It clears mClipToVisibleRegion on all layers.
|
|
* @param aClipRect the cliprect, in the root coordinate system. We assume
|
|
* that any layer drawing is clipped to this rect. It is therefore not
|
|
* allowed to add to the opaque region outside that rect.
|
|
* @param aDirtyRect the dirty rect that will be painted, in the root
|
|
* coordinate system. Layers outside this rect should be hidden.
|
|
* @param aOpaqueRegion the opaque region covering aLayer, in the
|
|
* root coordinate system.
|
|
*/
|
|
enum {
|
|
ALLOW_OPAQUE = 0x01,
|
|
};
|
|
static void
|
|
MarkLayersHidden(Layer* aLayer, const IntRect& aClipRect,
|
|
const IntRect& aDirtyRect,
|
|
nsIntRegion& aOpaqueRegion,
|
|
uint32_t aFlags)
|
|
{
|
|
IntRect newClipRect(aClipRect);
|
|
uint32_t newFlags = aFlags;
|
|
|
|
// Allow aLayer or aLayer's descendants to cover underlying layers
|
|
// only if it's opaque.
|
|
if (aLayer->GetOpacity() != 1.0f) {
|
|
newFlags &= ~ALLOW_OPAQUE;
|
|
}
|
|
|
|
{
|
|
const Maybe<ParentLayerIntRect>& clipRect = aLayer->GetEffectiveClipRect();
|
|
if (clipRect) {
|
|
IntRect cr = clipRect->ToUnknownRect();
|
|
// clipRect is in the container's coordinate system. Get it into the
|
|
// global coordinate system.
|
|
if (aLayer->GetParent()) {
|
|
Matrix tr;
|
|
if (aLayer->GetParent()->GetEffectiveTransform().CanDraw2D(&tr)) {
|
|
// Clip rect is applied after aLayer's transform, i.e., in the coordinate
|
|
// system of aLayer's parent.
|
|
TransformIntRect(cr, tr, ToInsideIntRect);
|
|
} else {
|
|
cr.SetRect(0, 0, 0, 0);
|
|
}
|
|
}
|
|
newClipRect.IntersectRect(newClipRect, cr);
|
|
}
|
|
}
|
|
|
|
BasicImplData* data = ToData(aLayer);
|
|
data->SetOperator(CompositionOp::OP_OVER);
|
|
data->SetClipToVisibleRegion(false);
|
|
data->SetDrawAtomically(false);
|
|
|
|
if (!aLayer->AsContainerLayer()) {
|
|
Matrix transform;
|
|
if (!aLayer->GetEffectiveTransform().CanDraw2D(&transform)) {
|
|
data->SetHidden(false);
|
|
return;
|
|
}
|
|
|
|
nsIntRegion region = aLayer->GetLocalVisibleRegion().ToUnknownRegion();
|
|
IntRect r = region.GetBounds();
|
|
TransformIntRect(r, transform, ToOutsideIntRect);
|
|
r.IntersectRect(r, aDirtyRect);
|
|
data->SetHidden(aOpaqueRegion.Contains(r));
|
|
|
|
// Allow aLayer to cover underlying layers only if aLayer's
|
|
// content is opaque
|
|
if ((aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE) &&
|
|
(newFlags & ALLOW_OPAQUE)) {
|
|
for (auto iter = region.RectIter(); !iter.Done(); iter.Next()) {
|
|
r = iter.Get();
|
|
TransformIntRect(r, transform, ToInsideIntRect);
|
|
|
|
r.IntersectRect(r, newClipRect);
|
|
aOpaqueRegion.Or(aOpaqueRegion, r);
|
|
}
|
|
}
|
|
} else {
|
|
Layer* child = aLayer->GetLastChild();
|
|
bool allHidden = true;
|
|
for (; child; child = child->GetPrevSibling()) {
|
|
MarkLayersHidden(child, newClipRect, aDirtyRect, aOpaqueRegion, newFlags);
|
|
if (!ToData(child)->IsHidden()) {
|
|
allHidden = false;
|
|
}
|
|
}
|
|
data->SetHidden(allHidden);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This function assumes that GetEffectiveTransform transforms
|
|
* all layers to the same coordinate system (the "root coordinate system").
|
|
* MarkLayersHidden must be called before calling this.
|
|
* @param aVisibleRect the rectangle of aLayer that is visible (i.e. not
|
|
* clipped and in the dirty rect), in the root coordinate system.
|
|
*/
|
|
static void
|
|
ApplyDoubleBuffering(Layer* aLayer, const IntRect& aVisibleRect)
|
|
{
|
|
BasicImplData* data = ToData(aLayer);
|
|
if (data->IsHidden())
|
|
return;
|
|
|
|
IntRect newVisibleRect(aVisibleRect);
|
|
|
|
{
|
|
const Maybe<ParentLayerIntRect>& clipRect = aLayer->GetEffectiveClipRect();
|
|
if (clipRect) {
|
|
IntRect cr = clipRect->ToUnknownRect();
|
|
// clipRect is in the container's coordinate system. Get it into the
|
|
// global coordinate system.
|
|
if (aLayer->GetParent()) {
|
|
Matrix tr;
|
|
if (aLayer->GetParent()->GetEffectiveTransform().CanDraw2D(&tr)) {
|
|
NS_ASSERTION(!ThebesMatrix(tr).HasNonIntegerTranslation(),
|
|
"Parent can only have an integer translation");
|
|
cr += nsIntPoint(int32_t(tr._31), int32_t(tr._32));
|
|
} else {
|
|
NS_ERROR("Parent can only have an integer translation");
|
|
}
|
|
}
|
|
newVisibleRect.IntersectRect(newVisibleRect, cr);
|
|
}
|
|
}
|
|
|
|
BasicContainerLayer* container =
|
|
static_cast<BasicContainerLayer*>(aLayer->AsContainerLayer());
|
|
// Layers that act as their own backbuffers should be drawn to the destination
|
|
// using OP_SOURCE to ensure that alpha values in a transparent window are
|
|
// cleared. This can also be faster than OP_OVER.
|
|
if (!container) {
|
|
data->SetOperator(CompositionOp::OP_SOURCE);
|
|
data->SetDrawAtomically(true);
|
|
} else {
|
|
if (container->UseIntermediateSurface() ||
|
|
!container->ChildrenPartitionVisibleRegion(newVisibleRect)) {
|
|
// We need to double-buffer this container.
|
|
data->SetOperator(CompositionOp::OP_SOURCE);
|
|
container->ForceIntermediateSurface();
|
|
} else {
|
|
// Tell the children to clip to their visible regions so our assumption
|
|
// that they don't paint outside their visible regions is valid!
|
|
for (Layer* child = aLayer->GetFirstChild(); child;
|
|
child = child->GetNextSibling()) {
|
|
ToData(child)->SetClipToVisibleRegion(true);
|
|
ApplyDoubleBuffering(child, newVisibleRect);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
BasicLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
|
|
void* aCallbackData,
|
|
EndTransactionFlags aFlags)
|
|
{
|
|
mInTransaction = false;
|
|
|
|
EndTransactionInternal(aCallback, aCallbackData, aFlags);
|
|
}
|
|
|
|
void
|
|
BasicLayerManager::AbortTransaction()
|
|
{
|
|
NS_ASSERTION(InConstruction(), "Should be in construction phase");
|
|
mPhase = PHASE_NONE;
|
|
mUsingDefaultTarget = false;
|
|
mInTransaction = false;
|
|
}
|
|
|
|
bool
|
|
BasicLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback,
|
|
void* aCallbackData,
|
|
EndTransactionFlags aFlags)
|
|
{
|
|
PROFILER_LABEL("BasicLayerManager", "EndTransactionInternal",
|
|
js::ProfileEntry::Category::GRAPHICS);
|
|
|
|
#ifdef MOZ_LAYERS_HAVE_LOG
|
|
MOZ_LAYERS_LOG((" ----- (beginning paint)"));
|
|
Log();
|
|
#endif
|
|
|
|
NS_ASSERTION(InConstruction(), "Should be in construction phase");
|
|
mPhase = PHASE_DRAWING;
|
|
|
|
RenderTraceLayers(mRoot, "FF00");
|
|
|
|
mTransactionIncomplete = false;
|
|
|
|
if (mRoot) {
|
|
if (aFlags & END_NO_COMPOSITE) {
|
|
// Apply pending tree updates before recomputing effective
|
|
// properties.
|
|
mRoot->ApplyPendingUpdatesToSubtree();
|
|
}
|
|
|
|
// Need to do this before we call ApplyDoubleBuffering,
|
|
// which depends on correct effective transforms
|
|
if (mTarget) {
|
|
mSnapEffectiveTransforms =
|
|
!mTarget->GetDrawTarget()->GetUserData(&sDisablePixelSnapping);
|
|
} else {
|
|
mSnapEffectiveTransforms = true;
|
|
}
|
|
mRoot->ComputeEffectiveTransforms(mTarget ? Matrix4x4::From2D(ToMatrix(mTarget->CurrentMatrix())) : Matrix4x4());
|
|
|
|
ToData(mRoot)->Validate(aCallback, aCallbackData, nullptr);
|
|
if (mRoot->GetMaskLayer()) {
|
|
ToData(mRoot->GetMaskLayer())->Validate(aCallback, aCallbackData, nullptr);
|
|
}
|
|
}
|
|
|
|
if (mTarget && mRoot &&
|
|
!(aFlags & END_NO_IMMEDIATE_REDRAW) &&
|
|
!(aFlags & END_NO_COMPOSITE)) {
|
|
IntRect clipRect;
|
|
|
|
{
|
|
gfxContextMatrixAutoSaveRestore save(mTarget);
|
|
mTarget->SetMatrix(gfxMatrix());
|
|
clipRect = ToOutsideIntRect(mTarget->GetClipExtents());
|
|
}
|
|
|
|
if (IsRetained()) {
|
|
nsIntRegion region;
|
|
MarkLayersHidden(mRoot, clipRect, clipRect, region, ALLOW_OPAQUE);
|
|
if (mUsingDefaultTarget && mDoubleBuffering != BufferMode::BUFFER_NONE) {
|
|
ApplyDoubleBuffering(mRoot, clipRect);
|
|
}
|
|
}
|
|
|
|
PaintLayer(mTarget, mRoot, aCallback, aCallbackData);
|
|
if (!mRegionToClear.IsEmpty()) {
|
|
for (auto iter = mRegionToClear.RectIter(); !iter.Done(); iter.Next()) {
|
|
const IntRect& r = iter.Get();
|
|
mTarget->GetDrawTarget()->ClearRect(Rect(r.x, r.y, r.width, r.height));
|
|
}
|
|
}
|
|
if (mWidget) {
|
|
FlashWidgetUpdateArea(mTarget);
|
|
}
|
|
RecordFrame();
|
|
PostPresent();
|
|
|
|
if (!mTransactionIncomplete) {
|
|
// Clear out target if we have a complete transaction.
|
|
mTarget = nullptr;
|
|
}
|
|
}
|
|
|
|
if (mRoot) {
|
|
mAnimationReadyTime = TimeStamp::Now();
|
|
mRoot->StartPendingAnimations(mAnimationReadyTime);
|
|
}
|
|
|
|
#ifdef MOZ_LAYERS_HAVE_LOG
|
|
Log();
|
|
MOZ_LAYERS_LOG(("]----- EndTransaction"));
|
|
#endif
|
|
|
|
// Go back to the construction phase if the transaction isn't complete.
|
|
// Layout will update the layer tree and call EndTransaction().
|
|
mPhase = mTransactionIncomplete ? PHASE_CONSTRUCTION : PHASE_NONE;
|
|
|
|
if (!mTransactionIncomplete) {
|
|
// This is still valid if the transaction was incomplete.
|
|
mUsingDefaultTarget = false;
|
|
}
|
|
|
|
NS_ASSERTION(!aCallback || !mTransactionIncomplete,
|
|
"If callback is not null, transaction must be complete");
|
|
|
|
// XXX - We should probably assert here that for an incomplete transaction
|
|
// out target is the default target.
|
|
|
|
return !mTransactionIncomplete;
|
|
}
|
|
|
|
void
|
|
BasicLayerManager::FlashWidgetUpdateArea(gfxContext *aContext)
|
|
{
|
|
if (gfxPrefs::WidgetUpdateFlashing()) {
|
|
float r = float(rand()) / RAND_MAX;
|
|
float g = float(rand()) / RAND_MAX;
|
|
float b = float(rand()) / RAND_MAX;
|
|
aContext->SetColor(Color(r, g, b, 0.2f));
|
|
aContext->Paint();
|
|
}
|
|
}
|
|
|
|
bool
|
|
BasicLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags)
|
|
{
|
|
mInTransaction = false;
|
|
|
|
if (!mRoot) {
|
|
return false;
|
|
}
|
|
|
|
return EndTransactionInternal(nullptr, nullptr, aFlags);
|
|
}
|
|
|
|
void
|
|
BasicLayerManager::SetRoot(Layer* aLayer)
|
|
{
|
|
NS_ASSERTION(aLayer, "Root can't be null");
|
|
NS_ASSERTION(aLayer->Manager() == this, "Wrong manager");
|
|
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
|
|
mRoot = aLayer;
|
|
}
|
|
|
|
void
|
|
BasicLayerManager::PaintSelfOrChildren(PaintLayerContext& aPaintContext,
|
|
gfxContext* aGroupTarget)
|
|
{
|
|
MOZ_ASSERT(aGroupTarget);
|
|
BasicImplData* data = ToData(aPaintContext.mLayer);
|
|
|
|
/* Only paint ourself, or our children - This optimization relies on this! */
|
|
Layer* child = aPaintContext.mLayer->GetFirstChild();
|
|
if (!child) {
|
|
if (aPaintContext.mLayer->AsPaintedLayer()) {
|
|
data->PaintThebes(aGroupTarget, aPaintContext.mLayer->GetMaskLayer(),
|
|
aPaintContext.mCallback, aPaintContext.mCallbackData);
|
|
} else {
|
|
data->Paint(aGroupTarget->GetDrawTarget(),
|
|
aGroupTarget->GetDeviceOffset(),
|
|
aPaintContext.mLayer->GetMaskLayer());
|
|
}
|
|
} else {
|
|
ContainerLayer* container =
|
|
static_cast<ContainerLayer*>(aPaintContext.mLayer);
|
|
AutoTArray<Layer*, 12> children;
|
|
container->SortChildrenBy3DZOrder(children);
|
|
for (uint32_t i = 0; i < children.Length(); i++) {
|
|
Layer* layer = children.ElementAt(i);
|
|
if (layer->IsBackfaceHidden()) {
|
|
continue;
|
|
}
|
|
if (!layer->AsContainerLayer() && !layer->IsVisible()) {
|
|
continue;
|
|
}
|
|
|
|
PaintLayer(aGroupTarget, layer, aPaintContext.mCallback,
|
|
aPaintContext.mCallbackData);
|
|
if (mTransactionIncomplete)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
BasicLayerManager::FlushGroup(PaintLayerContext& aPaintContext, bool aNeedsClipToVisibleRegion)
|
|
{
|
|
// If we're doing our own double-buffering, we need to avoid drawing
|
|
// the results of an incomplete transaction to the destination surface ---
|
|
// that could cause flicker. Double-buffering is implemented using a
|
|
// temporary surface for one or more container layers, so we need to stop
|
|
// those temporary surfaces from being composited to aTarget.
|
|
// ApplyDoubleBuffering guarantees that this container layer can't
|
|
// intersect any other leaf layers, so if the transaction is not yet marked
|
|
// incomplete, the contents of this container layer are the final contents
|
|
// for the window.
|
|
if (!mTransactionIncomplete) {
|
|
if (aNeedsClipToVisibleRegion) {
|
|
gfxUtils::ClipToRegion(aPaintContext.mTarget,
|
|
aPaintContext.mLayer->GetLocalVisibleRegion().ToUnknownRegion());
|
|
}
|
|
|
|
CompositionOp op = GetEffectiveOperator(aPaintContext.mLayer);
|
|
AutoSetOperator setOperator(aPaintContext.mTarget, op);
|
|
|
|
PaintWithMask(aPaintContext.mTarget, aPaintContext.mLayer->GetEffectiveOpacity(),
|
|
aPaintContext.mLayer->GetMaskLayer());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Install the clip applied to the layer on the given gfxContext. The
|
|
* given gfxContext is the buffer that the layer will be painted to.
|
|
*/
|
|
static void
|
|
InstallLayerClipPreserves3D(gfxContext* aTarget, Layer* aLayer)
|
|
{
|
|
const Maybe<ParentLayerIntRect> &clipRect = aLayer->GetEffectiveClipRect();
|
|
|
|
if (!clipRect) {
|
|
return;
|
|
}
|
|
MOZ_ASSERT(!aLayer->Extend3DContext() ||
|
|
!aLayer->Combines3DTransformWithAncestors(),
|
|
"Layers in a preserve 3D context have no clip"
|
|
" except leaves and the estabisher!");
|
|
|
|
Layer* parent = aLayer->GetParent();
|
|
Matrix4x4 transform3d =
|
|
parent && parent->Extend3DContext() ?
|
|
parent->GetEffectiveTransform() :
|
|
Matrix4x4();
|
|
Matrix transform;
|
|
if (!transform3d.CanDraw2D(&transform)) {
|
|
gfxDevCrash(LogReason::CannotDraw3D) << "GFX: We should not have a 3D transform that CanDraw2D() is false!";
|
|
}
|
|
gfxMatrix oldTransform = aTarget->CurrentMatrix();
|
|
transform *= ToMatrix(oldTransform);
|
|
aTarget->SetMatrix(ThebesMatrix(transform));
|
|
|
|
aTarget->NewPath();
|
|
aTarget->SnappedRectangle(gfxRect(clipRect->x, clipRect->y,
|
|
clipRect->width, clipRect->height));
|
|
aTarget->Clip();
|
|
|
|
aTarget->SetMatrix(oldTransform);
|
|
}
|
|
|
|
void
|
|
BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
|
Layer* aLayer,
|
|
DrawPaintedLayerCallback aCallback,
|
|
void* aCallbackData)
|
|
{
|
|
MOZ_ASSERT(aTarget);
|
|
|
|
PROFILER_LABEL("BasicLayerManager", "PaintLayer",
|
|
js::ProfileEntry::Category::GRAPHICS);
|
|
|
|
PaintLayerContext paintLayerContext(aTarget, aLayer, aCallback, aCallbackData);
|
|
|
|
// Don't attempt to paint layers with a singular transform, cairo will
|
|
// just throw an error.
|
|
if (aLayer->GetEffectiveTransform().IsSingular()) {
|
|
return;
|
|
}
|
|
|
|
RenderTraceScope trace("BasicLayerManager::PaintLayer", "707070");
|
|
|
|
const Maybe<ParentLayerIntRect>& clipRect = aLayer->GetEffectiveClipRect();
|
|
BasicContainerLayer* container =
|
|
static_cast<BasicContainerLayer*>(aLayer->AsContainerLayer());
|
|
bool needsGroup = container && container->UseIntermediateSurface();
|
|
BasicImplData* data = ToData(aLayer);
|
|
bool needsClipToVisibleRegion =
|
|
data->GetClipToVisibleRegion() && !aLayer->AsPaintedLayer();
|
|
NS_ASSERTION(needsGroup || !container ||
|
|
container->GetOperator() == CompositionOp::OP_OVER,
|
|
"non-OVER operator should have forced UseIntermediateSurface");
|
|
NS_ASSERTION(!container || !aLayer->GetMaskLayer() ||
|
|
container->UseIntermediateSurface(),
|
|
"ContainerLayer with mask layer should force UseIntermediateSurface");
|
|
|
|
gfxContextAutoSaveRestore contextSR;
|
|
gfxMatrix transform;
|
|
// Will return an identity matrix for 3d transforms, and is handled separately below.
|
|
bool is2D = paintLayerContext.Setup2DTransform();
|
|
MOZ_ASSERT(is2D || needsGroup || !container ||
|
|
container->Extend3DContext() ||
|
|
container->Is3DContextLeaf(),
|
|
"Must PushGroup for 3d transforms!");
|
|
|
|
Layer* parent = aLayer->GetParent();
|
|
bool inPreserves3DChain = parent && parent->Extend3DContext();
|
|
bool needsSaveRestore =
|
|
needsGroup || clipRect || needsClipToVisibleRegion || !is2D ||
|
|
inPreserves3DChain;
|
|
if (needsSaveRestore) {
|
|
contextSR.SetContext(aTarget);
|
|
|
|
// The clips on ancestors on the preserved3d chain should be
|
|
// installed on the aTarget before painting the layer.
|
|
InstallLayerClipPreserves3D(aTarget, aLayer);
|
|
for (Layer* l = parent; l && l->Extend3DContext(); l = l->GetParent()) {
|
|
InstallLayerClipPreserves3D(aTarget, l);
|
|
}
|
|
}
|
|
|
|
paintLayerContext.Apply2DTransform();
|
|
|
|
const nsIntRegion visibleRegion = aLayer->GetLocalVisibleRegion().ToUnknownRegion();
|
|
// If needsGroup is true, we'll clip to the visible region after we've popped the group
|
|
if (needsClipToVisibleRegion && !needsGroup) {
|
|
gfxUtils::ClipToRegion(aTarget, visibleRegion);
|
|
// Don't need to clip to visible region again
|
|
needsClipToVisibleRegion = false;
|
|
}
|
|
|
|
if (is2D) {
|
|
paintLayerContext.AnnotateOpaqueRect();
|
|
}
|
|
|
|
bool clipIsEmpty = aTarget->GetClipExtents().IsEmpty();
|
|
if (clipIsEmpty) {
|
|
PaintSelfOrChildren(paintLayerContext, aTarget);
|
|
return;
|
|
}
|
|
|
|
if (is2D) {
|
|
if (needsGroup) {
|
|
PushedGroup pushedGroup =
|
|
PushGroupForLayer(aTarget, aLayer, aLayer->GetLocalVisibleRegion().ToUnknownRegion());
|
|
PaintSelfOrChildren(paintLayerContext, pushedGroup.mGroupTarget);
|
|
PopGroupForLayer(pushedGroup);
|
|
} else {
|
|
PaintSelfOrChildren(paintLayerContext, aTarget);
|
|
}
|
|
} else {
|
|
if (!needsGroup && container) {
|
|
PaintSelfOrChildren(paintLayerContext, aTarget);
|
|
return;
|
|
}
|
|
|
|
const IntRect& bounds = visibleRegion.GetBounds();
|
|
RefPtr<DrawTarget> untransformedDT =
|
|
gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(IntSize(bounds.width, bounds.height),
|
|
SurfaceFormat::B8G8R8A8);
|
|
if (!untransformedDT || !untransformedDT->IsValid()) {
|
|
return;
|
|
}
|
|
|
|
RefPtr<gfxContext> groupTarget = gfxContext::ForDrawTarget(untransformedDT,
|
|
Point(bounds.x, bounds.y));
|
|
MOZ_ASSERT(groupTarget); // already checked the target above
|
|
|
|
PaintSelfOrChildren(paintLayerContext, groupTarget);
|
|
|
|
// Temporary fast fix for bug 725886
|
|
// Revert these changes when 725886 is ready
|
|
MOZ_ASSERT(untransformedDT && untransformedDT->IsValid(),
|
|
"We should always allocate an untransformed surface with 3d transforms!");
|
|
#ifdef DEBUG
|
|
if (aLayer->GetDebugColorIndex() != 0) {
|
|
Color color((aLayer->GetDebugColorIndex() & 1) ? 1.f : 0.f,
|
|
(aLayer->GetDebugColorIndex() & 2) ? 1.f : 0.f,
|
|
(aLayer->GetDebugColorIndex() & 4) ? 1.f : 0.f);
|
|
|
|
RefPtr<gfxContext> temp = gfxContext::ForDrawTarget(untransformedDT,
|
|
Point(bounds.x, bounds.y));
|
|
MOZ_ASSERT(temp); // already checked for target above
|
|
temp->SetColor(color);
|
|
temp->Paint();
|
|
}
|
|
#endif
|
|
Matrix4x4 effectiveTransform = aLayer->GetEffectiveTransform();
|
|
Rect xformBounds =
|
|
effectiveTransform.TransformAndClipBounds(Rect(bounds),
|
|
ToRect(aTarget->GetClipExtents()));
|
|
xformBounds.RoundOut();
|
|
effectiveTransform.PostTranslate(-xformBounds.x, -xformBounds.y, 0);
|
|
|
|
RefPtr<SourceSurface> untransformedSurf = untransformedDT->Snapshot();
|
|
RefPtr<DrawTarget> xformDT =
|
|
untransformedDT->CreateSimilarDrawTarget(IntSize(xformBounds.width, xformBounds.height),
|
|
SurfaceFormat::B8G8R8A8);
|
|
RefPtr<SourceSurface> xformSurf;
|
|
if(xformDT && untransformedSurf &&
|
|
xformDT->Draw3DTransformedSurface(untransformedSurf, effectiveTransform)) {
|
|
xformSurf = xformDT->Snapshot();
|
|
}
|
|
|
|
if (xformSurf) {
|
|
aTarget->SetPattern(
|
|
new gfxPattern(xformSurf,
|
|
Matrix::Translation(xformBounds.TopLeft())));
|
|
|
|
// Azure doesn't support EXTEND_NONE, so to avoid extending the edges
|
|
// of the source surface out to the current clip region, clip to
|
|
// the rectangle of the result surface now.
|
|
aTarget->NewPath();
|
|
aTarget->SnappedRectangle(ThebesRect(xformBounds));
|
|
aTarget->Clip();
|
|
FlushGroup(paintLayerContext, needsClipToVisibleRegion);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
BasicLayerManager::ClearCachedResources(Layer* aSubtree)
|
|
{
|
|
MOZ_ASSERT(!aSubtree || aSubtree->Manager() == this);
|
|
if (aSubtree) {
|
|
ClearLayer(aSubtree);
|
|
} else if (mRoot) {
|
|
ClearLayer(mRoot);
|
|
}
|
|
}
|
|
void
|
|
BasicLayerManager::ClearLayer(Layer* aLayer)
|
|
{
|
|
ToData(aLayer)->ClearCachedResources();
|
|
for (Layer* child = aLayer->GetFirstChild(); child;
|
|
child = child->GetNextSibling()) {
|
|
ClearLayer(child);
|
|
}
|
|
}
|
|
|
|
already_AddRefed<ReadbackLayer>
|
|
BasicLayerManager::CreateReadbackLayer()
|
|
{
|
|
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
|
|
RefPtr<ReadbackLayer> layer = new BasicReadbackLayer(this);
|
|
return layer.forget();
|
|
}
|
|
|
|
} // namespace layers
|
|
} // namespace mozilla
|