1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/Compositor.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,213 @@ 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 "mozilla/layers/Compositor.h" 1.10 +#include "base/message_loop.h" // for MessageLoop 1.11 +#include "mozilla/layers/CompositorParent.h" // for CompositorParent 1.12 +#include "mozilla/layers/Effects.h" // for Effect, EffectChain, etc 1.13 +#include "mozilla/mozalloc.h" // for operator delete, etc 1.14 +#include "gfx2DGlue.h" 1.15 + 1.16 +namespace mozilla { 1.17 +namespace gfx { 1.18 +class Matrix4x4; 1.19 +} 1.20 + 1.21 +namespace layers { 1.22 + 1.23 +/* static */ LayersBackend Compositor::sBackend = LayersBackend::LAYERS_NONE; 1.24 +/* static */ LayersBackend 1.25 +Compositor::GetBackend() 1.26 +{ 1.27 + AssertOnCompositorThread(); 1.28 + return sBackend; 1.29 +} 1.30 + 1.31 +/* static */ void 1.32 +Compositor::SetBackend(LayersBackend backend) 1.33 +{ 1.34 + if (sBackend != LayersBackend::LAYERS_NONE && sBackend != backend) { 1.35 + // Assert this once we figure out bug 972891. 1.36 + //MOZ_CRASH("Trying to use more than one OMTC compositor."); 1.37 + 1.38 +#ifdef XP_MACOSX 1.39 + printf("ERROR: Changing compositor from %u to %u.\n", 1.40 + unsigned(sBackend), unsigned(backend)); 1.41 +#endif 1.42 + } 1.43 + sBackend = backend; 1.44 +} 1.45 + 1.46 +/* static */ void 1.47 +Compositor::AssertOnCompositorThread() 1.48 +{ 1.49 + MOZ_ASSERT(CompositorParent::CompositorLoop() == 1.50 + MessageLoop::current(), 1.51 + "Can only call this from the compositor thread!"); 1.52 +} 1.53 + 1.54 +bool 1.55 +Compositor::ShouldDrawDiagnostics(DiagnosticFlags aFlags) 1.56 +{ 1.57 + if ((aFlags & DIAGNOSTIC_TILE) && !(mDiagnosticTypes & DIAGNOSTIC_TILE_BORDERS)) { 1.58 + return false; 1.59 + } 1.60 + if ((aFlags & DIAGNOSTIC_BIGIMAGE) && 1.61 + !(mDiagnosticTypes & DIAGNOSTIC_BIGIMAGE_BORDERS)) { 1.62 + return false; 1.63 + } 1.64 + if (!mDiagnosticTypes) { 1.65 + return false; 1.66 + } 1.67 + return true; 1.68 +} 1.69 + 1.70 +void 1.71 +Compositor::DrawDiagnostics(DiagnosticFlags aFlags, 1.72 + const nsIntRegion& aVisibleRegion, 1.73 + const gfx::Rect& aClipRect, 1.74 + const gfx::Matrix4x4& aTransform, 1.75 + uint32_t aFlashCounter) 1.76 +{ 1.77 + if (!ShouldDrawDiagnostics(aFlags)) { 1.78 + return; 1.79 + } 1.80 + 1.81 + if (aVisibleRegion.GetNumRects() > 1) { 1.82 + nsIntRegionRectIterator screenIter(aVisibleRegion); 1.83 + 1.84 + while (const nsIntRect* rect = screenIter.Next()) 1.85 + { 1.86 + DrawDiagnostics(aFlags | DIAGNOSTIC_REGION_RECT, 1.87 + ToRect(*rect), aClipRect, aTransform, aFlashCounter); 1.88 + } 1.89 + } 1.90 + 1.91 + DrawDiagnostics(aFlags, ToRect(aVisibleRegion.GetBounds()), 1.92 + aClipRect, aTransform, aFlashCounter); 1.93 +} 1.94 + 1.95 +void 1.96 +Compositor::DrawDiagnostics(DiagnosticFlags aFlags, 1.97 + const gfx::Rect& aVisibleRect, 1.98 + const gfx::Rect& aClipRect, 1.99 + const gfx::Matrix4x4& aTransform, 1.100 + uint32_t aFlashCounter) 1.101 +{ 1.102 + if (!ShouldDrawDiagnostics(aFlags)) { 1.103 + return; 1.104 + } 1.105 + 1.106 + DrawDiagnosticsInternal(aFlags, aVisibleRect, aClipRect, aTransform, 1.107 + aFlashCounter); 1.108 +} 1.109 + 1.110 +gfx::Rect 1.111 +Compositor::ClipRectInLayersCoordinates(gfx::Rect aClip) const { 1.112 + gfx::Rect result; 1.113 + aClip = aClip + GetCurrentRenderTarget()->GetOrigin(); 1.114 + gfx::IntSize destSize = GetWidgetSize(); 1.115 + 1.116 + switch (mScreenRotation) { 1.117 + case ROTATION_0: 1.118 + result = aClip; 1.119 + break; 1.120 + case ROTATION_90: 1.121 + result = gfx::Rect(aClip.y, 1.122 + destSize.width - aClip.x - aClip.width, 1.123 + aClip.height, aClip.width); 1.124 + break; 1.125 + case ROTATION_270: 1.126 + result = gfx::Rect(destSize.height - aClip.y - aClip.height, 1.127 + aClip.x, 1.128 + aClip.height, aClip.width); 1.129 + break; 1.130 + case ROTATION_180: 1.131 + result = gfx::Rect(destSize.width - aClip.x - aClip.width, 1.132 + destSize.height - aClip.y - aClip.height, 1.133 + aClip.width, aClip.height); 1.134 + break; 1.135 + // ScreenRotation has a sentinel value, need to catch it in the switch 1.136 + // statement otherwise the build fails (-WError) 1.137 + default: {} 1.138 + } 1.139 + return result; 1.140 +} 1.141 + 1.142 +void 1.143 +Compositor::DrawDiagnosticsInternal(DiagnosticFlags aFlags, 1.144 + const gfx::Rect& aVisibleRect, 1.145 + const gfx::Rect& aClipRect, 1.146 + const gfx::Matrix4x4& aTransform, 1.147 + uint32_t aFlashCounter) 1.148 +{ 1.149 +#ifdef MOZ_B2G 1.150 + int lWidth = 4; 1.151 +#elif defined(ANDROID) 1.152 + int lWidth = 10; 1.153 +#else 1.154 + int lWidth = 2; 1.155 +#endif 1.156 + float opacity = 0.7f; 1.157 + 1.158 + gfx::Color color; 1.159 + if (aFlags & DIAGNOSTIC_CONTENT) { 1.160 + color = gfx::Color(0.0f, 1.0f, 0.0f, 1.0f); // green 1.161 + if (aFlags & DIAGNOSTIC_COMPONENT_ALPHA) { 1.162 + color = gfx::Color(0.0f, 1.0f, 1.0f, 1.0f); // greenish blue 1.163 + } 1.164 + } else if (aFlags & DIAGNOSTIC_IMAGE) { 1.165 + color = gfx::Color(1.0f, 0.0f, 0.0f, 1.0f); // red 1.166 + } else if (aFlags & DIAGNOSTIC_COLOR) { 1.167 + color = gfx::Color(0.0f, 0.0f, 1.0f, 1.0f); // blue 1.168 + } else if (aFlags & DIAGNOSTIC_CONTAINER) { 1.169 + color = gfx::Color(0.8f, 0.0f, 0.8f, 1.0f); // purple 1.170 + } 1.171 + 1.172 + // make tile borders a bit more transparent to keep layer borders readable. 1.173 + if (aFlags & DIAGNOSTIC_TILE || 1.174 + aFlags & DIAGNOSTIC_BIGIMAGE || 1.175 + aFlags & DIAGNOSTIC_REGION_RECT) { 1.176 + lWidth = 1; 1.177 + opacity = 0.5f; 1.178 + color.r *= 0.7f; 1.179 + color.g *= 0.7f; 1.180 + color.b *= 0.7f; 1.181 + } 1.182 + 1.183 + if (mDiagnosticTypes & DIAGNOSTIC_FLASH_BORDERS) { 1.184 + float flash = (float)aFlashCounter / (float)DIAGNOSTIC_FLASH_COUNTER_MAX; 1.185 + color.r *= flash; 1.186 + color.g *= flash; 1.187 + color.b *= flash; 1.188 + } 1.189 + 1.190 + EffectChain effects; 1.191 + 1.192 + effects.mPrimaryEffect = new EffectSolidColor(color); 1.193 + // left 1.194 + this->DrawQuad(gfx::Rect(aVisibleRect.x, aVisibleRect.y, 1.195 + lWidth, aVisibleRect.height), 1.196 + aClipRect, effects, opacity, 1.197 + aTransform); 1.198 + // top 1.199 + this->DrawQuad(gfx::Rect(aVisibleRect.x + lWidth, aVisibleRect.y, 1.200 + aVisibleRect.width - 2 * lWidth, lWidth), 1.201 + aClipRect, effects, opacity, 1.202 + aTransform); 1.203 + // right 1.204 + this->DrawQuad(gfx::Rect(aVisibleRect.x + aVisibleRect.width - lWidth, aVisibleRect.y, 1.205 + lWidth, aVisibleRect.height), 1.206 + aClipRect, effects, opacity, 1.207 + aTransform); 1.208 + // bottom 1.209 + this->DrawQuad(gfx::Rect(aVisibleRect.x + lWidth, aVisibleRect.y + aVisibleRect.height-lWidth, 1.210 + aVisibleRect.width - 2 * lWidth, lWidth), 1.211 + aClipRect, effects, opacity, 1.212 + aTransform); 1.213 +} 1.214 + 1.215 +} // namespace 1.216 +} // namespace