1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/client/ClientThebesLayer.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,166 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; 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 "ClientThebesLayer.h" 1.10 +#include "ClientTiledThebesLayer.h" // for ClientTiledThebesLayer 1.11 +#include "SimpleTiledContentClient.h" 1.12 +#include <stdint.h> // for uint32_t 1.13 +#include "GeckoProfiler.h" // for PROFILER_LABEL 1.14 +#include "client/ClientLayerManager.h" // for ClientLayerManager, etc 1.15 +#include "gfxContext.h" // for gfxContext 1.16 +#include "gfxRect.h" // for gfxRect 1.17 +#include "gfxPrefs.h" // for gfxPrefs 1.18 +#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc 1.19 +#include "mozilla/gfx/2D.h" // for DrawTarget 1.20 +#include "mozilla/gfx/Matrix.h" // for Matrix 1.21 +#include "mozilla/gfx/Rect.h" // for Rect, IntRect 1.22 +#include "mozilla/gfx/Types.h" // for Float, etc 1.23 +#include "mozilla/layers/LayersTypes.h" 1.24 +#include "mozilla/Preferences.h" 1.25 +#include "nsAutoPtr.h" // for nsRefPtr 1.26 +#include "nsCOMPtr.h" // for already_AddRefed 1.27 +#include "nsISupportsImpl.h" // for Layer::AddRef, etc 1.28 +#include "nsRect.h" // for nsIntRect 1.29 +#include "gfx2DGlue.h" 1.30 + 1.31 +using namespace mozilla::gfx; 1.32 + 1.33 +namespace mozilla { 1.34 +namespace layers { 1.35 + 1.36 +void 1.37 +ClientThebesLayer::PaintThebes() 1.38 +{ 1.39 + PROFILER_LABEL("ClientThebesLayer", "PaintThebes"); 1.40 + NS_ASSERTION(ClientManager()->InDrawing(), 1.41 + "Can only draw in drawing phase"); 1.42 + 1.43 + uint32_t flags = RotatedContentBuffer::PAINT_CAN_DRAW_ROTATED; 1.44 +#ifndef MOZ_WIDGET_ANDROID 1.45 + if (ClientManager()->CompositorMightResample()) { 1.46 + flags |= RotatedContentBuffer::PAINT_WILL_RESAMPLE; 1.47 + } 1.48 + if (!(flags & RotatedContentBuffer::PAINT_WILL_RESAMPLE)) { 1.49 + if (MayResample()) { 1.50 + flags |= RotatedContentBuffer::PAINT_WILL_RESAMPLE; 1.51 + } 1.52 + } 1.53 +#endif 1.54 + PaintState state = 1.55 + mContentClient->BeginPaintBuffer(this, flags); 1.56 + mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate); 1.57 + 1.58 + if (!state.mRegionToDraw.IsEmpty() && !ClientManager()->GetThebesLayerCallback()) { 1.59 + ClientManager()->SetTransactionIncomplete(); 1.60 + return; 1.61 + } 1.62 + 1.63 + // The area that became invalid and is visible needs to be repainted 1.64 + // (this could be the whole visible area if our buffer switched 1.65 + // from RGB to RGBA, because we might need to repaint with 1.66 + // subpixel AA) 1.67 + state.mRegionToInvalidate.And(state.mRegionToInvalidate, 1.68 + GetEffectiveVisibleRegion()); 1.69 + 1.70 + bool didUpdate = false; 1.71 + RotatedContentBuffer::DrawIterator iter; 1.72 + while (DrawTarget* target = mContentClient->BorrowDrawTargetForPainting(state, &iter)) { 1.73 + SetAntialiasingFlags(this, target); 1.74 + 1.75 + nsRefPtr<gfxContext> ctx = gfxContext::ContextForDrawTarget(target); 1.76 + 1.77 + ClientManager()->GetThebesLayerCallback()(this, 1.78 + ctx, 1.79 + iter.mDrawRegion, 1.80 + state.mClip, 1.81 + state.mRegionToInvalidate, 1.82 + ClientManager()->GetThebesLayerCallbackData()); 1.83 + 1.84 + ctx = nullptr; 1.85 + mContentClient->ReturnDrawTargetToBuffer(target); 1.86 + didUpdate = true; 1.87 + } 1.88 + 1.89 + if (didUpdate) { 1.90 + Mutated(); 1.91 + 1.92 + mValidRegion.Or(mValidRegion, state.mRegionToDraw); 1.93 + 1.94 + ContentClientRemote* contentClientRemote = static_cast<ContentClientRemote*>(mContentClient.get()); 1.95 + MOZ_ASSERT(contentClientRemote->GetIPDLActor()); 1.96 + 1.97 + // Hold(this) ensures this layer is kept alive through the current transaction 1.98 + // The ContentClient assumes this layer is kept alive (e.g., in CreateBuffer), 1.99 + // so deleting this Hold for whatever reason will break things. 1.100 + ClientManager()->Hold(this); 1.101 + contentClientRemote->Updated(state.mRegionToDraw, 1.102 + mVisibleRegion, 1.103 + state.mDidSelfCopy); 1.104 + } 1.105 +} 1.106 + 1.107 +void 1.108 +ClientThebesLayer::RenderLayer() 1.109 +{ 1.110 + if (GetMaskLayer()) { 1.111 + ToClientLayer(GetMaskLayer())->RenderLayer(); 1.112 + } 1.113 + 1.114 + if (!mContentClient) { 1.115 + mContentClient = ContentClient::CreateContentClient(ClientManager()->AsShadowForwarder()); 1.116 + if (!mContentClient) { 1.117 + return; 1.118 + } 1.119 + mContentClient->Connect(); 1.120 + ClientManager()->AsShadowForwarder()->Attach(mContentClient, this); 1.121 + MOZ_ASSERT(mContentClient->GetForwarder()); 1.122 + } 1.123 + 1.124 + mContentClient->BeginPaint(); 1.125 + PaintThebes(); 1.126 + mContentClient->EndPaint(); 1.127 +} 1.128 + 1.129 +already_AddRefed<ThebesLayer> 1.130 +ClientLayerManager::CreateThebesLayer() 1.131 +{ 1.132 + return CreateThebesLayerWithHint(NONE); 1.133 +} 1.134 + 1.135 +already_AddRefed<ThebesLayer> 1.136 +ClientLayerManager::CreateThebesLayerWithHint(ThebesLayerCreationHint aHint) 1.137 +{ 1.138 + NS_ASSERTION(InConstruction(), "Only allowed in construction phase"); 1.139 + if ( 1.140 +#ifdef MOZ_B2G 1.141 + aHint == SCROLLABLE && 1.142 +#endif 1.143 + gfxPrefs::LayersTilesEnabled() && 1.144 + (AsShadowForwarder()->GetCompositorBackendType() == LayersBackend::LAYERS_OPENGL || 1.145 + AsShadowForwarder()->GetCompositorBackendType() == LayersBackend::LAYERS_D3D9 || 1.146 + AsShadowForwarder()->GetCompositorBackendType() == LayersBackend::LAYERS_D3D11)) { 1.147 + if (gfxPrefs::LayersUseSimpleTiles()) { 1.148 + nsRefPtr<SimpleClientTiledThebesLayer> layer = 1.149 + new SimpleClientTiledThebesLayer(this); 1.150 + CREATE_SHADOW(Thebes); 1.151 + return layer.forget(); 1.152 + } else { 1.153 + nsRefPtr<ClientTiledThebesLayer> layer = 1.154 + new ClientTiledThebesLayer(this); 1.155 + CREATE_SHADOW(Thebes); 1.156 + return layer.forget(); 1.157 + } 1.158 + } else 1.159 + { 1.160 + nsRefPtr<ClientThebesLayer> layer = 1.161 + new ClientThebesLayer(this); 1.162 + CREATE_SHADOW(Thebes); 1.163 + return layer.forget(); 1.164 + } 1.165 +} 1.166 + 1.167 + 1.168 +} 1.169 +}