gecko-dev/gfx/layers/basic/BasicCanvasLayer.cpp

142 строки
3.8 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 "BasicCanvasLayer.h"
#include "AsyncCanvasRenderer.h"
#include "basic/BasicLayers.h" // for BasicLayerManager
#include "basic/BasicLayersImpl.h" // for GetEffectiveOperator
#include "mozilla/mozalloc.h" // for operator new
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsISupportsImpl.h" // for Layer::AddRef, etc
#include "gfx2DGlue.h"
#include "GLScreenBuffer.h"
#include "GLContext.h"
#include "gfxUtils.h"
#include "mozilla/layers/PersistentBufferProvider.h"
#include "client/TextureClientSharedSurface.h"
class gfxContext;
using namespace mozilla::gfx;
using namespace mozilla::gl;
namespace mozilla {
namespace layers {
already_AddRefed<SourceSurface>
BasicCanvasLayer::UpdateSurface()
{
if (mAsyncRenderer) {
MOZ_ASSERT(!mBufferProvider);
MOZ_ASSERT(!mGLContext);
return mAsyncRenderer->GetSurface();
}
if (!mGLContext) {
return nullptr;
}
SharedSurface* frontbuffer = nullptr;
if (mGLFrontbuffer) {
frontbuffer = mGLFrontbuffer.get();
} else {
GLScreenBuffer* screen = mGLContext->Screen();
const auto& front = screen->Front();
if (front) {
frontbuffer = front->Surf();
}
}
if (!frontbuffer) {
NS_WARNING("Null frame received.");
return nullptr;
}
IntSize readSize(frontbuffer->mSize);
SurfaceFormat format = (GetContentFlags() & CONTENT_OPAQUE)
? SurfaceFormat::B8G8R8X8
: SurfaceFormat::B8G8R8A8;
bool needsPremult = frontbuffer->mHasAlpha && !mIsAlphaPremultiplied;
RefPtr<DataSourceSurface> resultSurf = GetTempSurface(readSize, format);
// There will already be a warning from inside of GetTempSurface, but
// it doesn't hurt to complain:
if (NS_WARN_IF(!resultSurf)) {
return nullptr;
}
// Readback handles Flush/MarkDirty.
mGLContext->Readback(frontbuffer, resultSurf);
if (needsPremult) {
gfxUtils::PremultiplyDataSurface(resultSurf, resultSurf);
}
MOZ_ASSERT(resultSurf);
return resultSurf.forget();
}
void
BasicCanvasLayer::Paint(DrawTarget* aDT,
const Point& aDeviceOffset,
Layer* aMaskLayer)
{
if (IsHidden())
return;
RefPtr<SourceSurface> surface;
if (IsDirty()) {
Painted();
FirePreTransactionCallback();
surface = UpdateSurface();
FireDidTransactionCallback();
}
bool bufferPoviderSnapshot = false;
if (!surface && mBufferProvider) {
surface = mBufferProvider->BorrowSnapshot();
bufferPoviderSnapshot = !!surface;
}
if (!surface) {
return;
}
const bool needsYFlip = (mOriginPos == gl::OriginPos::BottomLeft);
Matrix oldTM;
if (needsYFlip) {
oldTM = aDT->GetTransform();
aDT->SetTransform(Matrix(oldTM).
PreTranslate(0.0f, mBounds.height).
PreScale(1.0f, -1.0f));
}
FillRectWithMask(aDT, aDeviceOffset,
Rect(0, 0, mBounds.width, mBounds.height),
surface, mSamplingFilter,
DrawOptions(GetEffectiveOpacity(), GetEffectiveOperator(this)),
aMaskLayer);
if (needsYFlip) {
aDT->SetTransform(oldTM);
}
if (bufferPoviderSnapshot) {
mBufferProvider->ReturnSnapshot(surface.forget());
}
}
already_AddRefed<CanvasLayer>
BasicLayerManager::CreateCanvasLayer()
{
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<CanvasLayer> layer = new BasicCanvasLayer(this);
return layer.forget();
}
} // namespace layers
} // namespace mozilla