1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/basic/BasicImageLayer.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,152 @@ 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 "BasicLayersImpl.h" // for FillRectWithMask, etc 1.10 +#include "ImageContainer.h" // for AutoLockImage, etc 1.11 +#include "ImageLayers.h" // for ImageLayer 1.12 +#include "Layers.h" // for Layer (ptr only), etc 1.13 +#include "basic/BasicImplData.h" // for BasicImplData 1.14 +#include "basic/BasicLayers.h" // for BasicLayerManager 1.15 +#include "mozilla/mozalloc.h" // for operator new 1.16 +#include "nsAutoPtr.h" // for nsRefPtr, getter_AddRefs, etc 1.17 +#include "nsCOMPtr.h" // for already_AddRefed 1.18 +#include "nsDebug.h" // for NS_ASSERTION 1.19 +#include "nsISupportsImpl.h" // for gfxPattern::Release, etc 1.20 +#include "nsRect.h" // for nsIntRect 1.21 +#include "nsRegion.h" // for nsIntRegion 1.22 +#include "mozilla/gfx/Point.h" // for IntSize 1.23 + 1.24 +using namespace mozilla::gfx; 1.25 + 1.26 +namespace mozilla { 1.27 +namespace layers { 1.28 + 1.29 +class BasicImageLayer : public ImageLayer, public BasicImplData { 1.30 +public: 1.31 + BasicImageLayer(BasicLayerManager* aLayerManager) : 1.32 + ImageLayer(aLayerManager, 1.33 + static_cast<BasicImplData*>(MOZ_THIS_IN_INITIALIZER_LIST())), 1.34 + mSize(-1, -1) 1.35 + { 1.36 + MOZ_COUNT_CTOR(BasicImageLayer); 1.37 + } 1.38 + virtual ~BasicImageLayer() 1.39 + { 1.40 + MOZ_COUNT_DTOR(BasicImageLayer); 1.41 + } 1.42 + 1.43 + virtual void SetVisibleRegion(const nsIntRegion& aRegion) 1.44 + { 1.45 + NS_ASSERTION(BasicManager()->InConstruction(), 1.46 + "Can only set properties in construction phase"); 1.47 + ImageLayer::SetVisibleRegion(aRegion); 1.48 + } 1.49 + 1.50 + virtual void Paint(DrawTarget* aDT, 1.51 + const gfx::Point& aDeviceOffset, 1.52 + Layer* aMaskLayer) MOZ_OVERRIDE; 1.53 + 1.54 + virtual TemporaryRef<SourceSurface> GetAsSourceSurface() MOZ_OVERRIDE; 1.55 + 1.56 +protected: 1.57 + BasicLayerManager* BasicManager() 1.58 + { 1.59 + return static_cast<BasicLayerManager*>(mManager); 1.60 + } 1.61 + 1.62 + // only paints the image if aContext is non-null 1.63 + void 1.64 + GetAndPaintCurrentImage(DrawTarget* aTarget, 1.65 + float aOpacity, 1.66 + SourceSurface* aMaskSurface); 1.67 + 1.68 + gfx::IntSize mSize; 1.69 +}; 1.70 + 1.71 +void 1.72 +BasicImageLayer::Paint(DrawTarget* aDT, 1.73 + const gfx::Point& aDeviceOffset, 1.74 + Layer* aMaskLayer) 1.75 +{ 1.76 + if (IsHidden() || !mContainer) { 1.77 + return; 1.78 + } 1.79 + 1.80 + mContainer->SetImageFactory(mManager->IsCompositingCheap() ? nullptr : BasicManager()->GetImageFactory()); 1.81 + 1.82 + RefPtr<gfx::SourceSurface> surface; 1.83 + AutoLockImage autoLock(mContainer, &surface); 1.84 + Image *image = autoLock.GetImage(); 1.85 + gfx::IntSize size = mSize = autoLock.GetSize(); 1.86 + 1.87 + if (!surface || !surface->IsValid()) { 1.88 + return; 1.89 + } 1.90 + 1.91 + FillRectWithMask(aDT, aDeviceOffset, Rect(0, 0, size.width, size.height), 1.92 + surface, ToFilter(mFilter), 1.93 + DrawOptions(GetEffectiveOpacity(), GetEffectiveOperator(this)), 1.94 + aMaskLayer); 1.95 + 1.96 + GetContainer()->NotifyPaintedImage(image); 1.97 +} 1.98 + 1.99 +void 1.100 +BasicImageLayer::GetAndPaintCurrentImage(DrawTarget* aTarget, 1.101 + float aOpacity, 1.102 + SourceSurface* aMaskSurface) 1.103 +{ 1.104 + if (!mContainer) { 1.105 + return; 1.106 + } 1.107 + 1.108 + mContainer->SetImageFactory(mManager->IsCompositingCheap() ? 1.109 + nullptr : 1.110 + BasicManager()->GetImageFactory()); 1.111 + IntSize size; 1.112 + Image* image = nullptr; 1.113 + RefPtr<SourceSurface> surf = 1.114 + mContainer->LockCurrentAsSourceSurface(&size, &image); 1.115 + 1.116 + if (!surf) { 1.117 + return; 1.118 + } 1.119 + 1.120 + if (aTarget) { 1.121 + // The visible region can extend outside the image, so just draw 1.122 + // within the image bounds. 1.123 + SurfacePattern pat(surf, ExtendMode::CLAMP, Matrix(), ToFilter(mFilter)); 1.124 + CompositionOp op = GetEffectiveOperator(this); 1.125 + DrawOptions opts(aOpacity, op); 1.126 + 1.127 + aTarget->MaskSurface(pat, aMaskSurface, Point(0, 0), opts); 1.128 + 1.129 + GetContainer()->NotifyPaintedImage(image); 1.130 + } 1.131 + 1.132 + mContainer->UnlockCurrentImage(); 1.133 +} 1.134 + 1.135 +TemporaryRef<SourceSurface> 1.136 +BasicImageLayer::GetAsSourceSurface() 1.137 +{ 1.138 + if (!mContainer) { 1.139 + return nullptr; 1.140 + } 1.141 + 1.142 + gfx::IntSize dontCare; 1.143 + return mContainer->GetCurrentAsSourceSurface(&dontCare); 1.144 +} 1.145 + 1.146 +already_AddRefed<ImageLayer> 1.147 +BasicLayerManager::CreateImageLayer() 1.148 +{ 1.149 + NS_ASSERTION(InConstruction(), "Only allowed in construction phase"); 1.150 + nsRefPtr<ImageLayer> layer = new BasicImageLayer(this); 1.151 + return layer.forget(); 1.152 +} 1.153 + 1.154 +} 1.155 +}