mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:30:27 +00:00
ee05861206
- Bug 1187056 - Dispatch the meta tag mutation events sooner so that any meta-viewport changes can be processed before scripts continue running. r=smaug (2e6f76079f)
- Bug 1238804. Make <base> actually work in a srcdoc document. r=smaug (a421e7c598)
- Bug 1239585 - Remove eSupportSVG from nsObjectLoadingContent capabilities; r=bz (68a79ef21b)
- Bug 1170572 - MQ CSS change not observed by picture source elements r=jdm (efc0be616e)
- Bug 1206720 - Remove invalid assertions during response image loading. r=jdm (0b6485de95)
- Bug 1229032 - don't copy arrays in PerformanceObserver::Observe; r=baku (f1b70e0bd2)
- Bug 1241840 - Set table cell colspan=0 to 1 instead per the HTML spec. r=bz (1900962d4c)
- Bug 812899 part 1. Split the "image is overflow" concept in ImageDocument into two separate booleans for vertical and horizontal overflow. r=khuey (8735b610f3)
- Bug 812899 part 2. Change the centering code in nsImageDocument to only try vertically centering via auto margins when we're not overflowing in the vertical direction, because if we _are_ overflowing that should cut off part of the image per spec. r=khuey (c3b84a8048)
- Bug 812899 part 3 - Make vertical 'auto' margins on absolutely positioned elements always center, even when the margins are negative. r=dbaron (e345fb9383)
- Bug 1238427 - Avoid a strong reference from the timeout timer to nsGeolocationRequest. r=jdm (2ad4dd3955)
- Bug 1240906 - Shut down geolocation service at xpcom-shutdown instead of quit-application. r=dougt (1e7fc9e624)
- Bug 1129633 - part1. Use win8 geolocation with a fallback to MLS - r=m_kato (3323b4a120)
- Bug 1145111: ensure the pos. cache isn't reset when nsGeolocationService shuts down provider. r=jdm (e69cab889a)
- Bug 1240664 - Only enable bug 1216148's behavior when there is a wakelock support. r=kanru (543a3a55b4)
- Bug 1240766 - Fix startup crash in Geolocation::Init() when principal URI is null r=jdm (1ece684418)
- Bug 1238873 - Handle the bug that if we take cached data, we might not get any update later. r=kchen. r=jdm. (ca186e89b3)
- Bug 1240666 - Follow-up to bug 1216148. r=kchen. (3f650b5f72)
- Bug 1227119 - Set a default value for variable ret. r=dougt (5b68dd1a22)
- Bug 1027734 - Convert mozPay to WebIDL. r=bzbarsky. (a4fd10d539)
- Bug 1214488 - Allow native callers in GetEntryGlobal. r=me (ca68cc8896)
- Bug 1248719. Fix things so that taking ownership of error reporting on an AutoJSAPI on a worker is OK even if that AutoJSAPI was initialized without an explicit global. r=bholley (b8e59eebc6)
- Bug 1156065 - Send cloneable messages from SiteSpecificUserAgent.js to fix UA overrides r=billm (e5cdbe96f6)
- Bug 1210099 - Fix structured clone of expanded principal (r=bholley) (01a5fd4e47)
- Bug 1230351: Replace ThirdPartyUtil::IsThirdPartyInternal's warning-spammy NS_ENSURE_ARG with an equivalent check that lacks the warning. r=mrbkap (037c39472c)
- Bug 1184293 - Don't call ThirdPartyUtil::GetBaseDomain if aUri is null. r=jduell (4853c0e9e0)
- Bug 862147 - instrument usage of window.sidebar.addSearchEngine, r=froydnj,smaug. (ef52ded1c0)
- Bug 1214764 - Convert NS_ENSURE to a plain return in nsDocument::IsScriptEnabled. r=bholley (0f3b6d63b4)
- Bug 1245950: Privately inherit from legacy interfaces nsIDOMWindow/nsIDOMWindowInternal. r=smaug (ff1d431d0d)
- Bug 1245950: Followup to null check before asserting. r=me CLOSED TREE (6e93af4a4a)
- Bug 1236607, pointerlock code should null check inner window before using it, r=xidorn (896d9723d5)
- Bug 1245245 - Fix typo in error string URL. r=botond (58c9548f15)
- Bug 1220604 - Remove dead code from nsGlobalWindow::SetNewDocument. r=baku (fc875db5e4)
- Bug 1247049 - Optimize GetScreenXY by using the new nsDeviceContext method to get desktop scale factor. r=emk (de66d59631)
- missing bit of Bug 962249 part 3 (0b15f8b670)
- Bug 1240978 - Shorten timeout for black screen in fullscreen transition. r=smaug (2554a8e5a7)
- Bug 1246346 - patch 1 - Expose a DesktopToDevice scale factor on nsDeviceContext. r=emk (03856ec7b4)
- Bug 1246346 - patch 2 - Correct the origin of the DOM screen coordinates (screen.left, screen.top) for secondary display on a mixed-DPI configuration. r=emk (15ac2d3be6)
- Bug 1196159 - Set nsGlobalWindow::mIsClosed properly after window.close(). r=billm (27334e4b61)
- Bug 1240241 - Don't recurse infinitely in FilterCachedColorModels::ForColorModel if the original filter node was null. r=roc (1730db5ca7)
- Bug 1247706 - "Please don't disable WebGL if crashed on WebGL context". r=dvander (e25621753e)
- Bug 1244742. Use the default copy constructor and assignment operators. (0dac3bcbfb)
- Bug 1230929 - modified the logic in order to prvent null pointer dereference. r=jmuizelaar (1d5761abc9)
- Bug 1247979. Optimize ScaleToOutsidePixels. r=kats (2b9ef41111)
- Bug 1249368 - use UniquePtr instead of nsAutoArrayPtr in gfxAlphaBoxBlur; r=jrmuizel (e60419d49d)
- Bug 1082598 - Part 4: Workaround for naming conflict in unified sources for Skia and thebes DWrite fonts. r=jrmuizel (84a9e11ded)
- Bug 1172817 - Remove PL_DHashTableEnumerate() use from FontNameCache. r=jtd. (b0632cd825)
- Bug 1197717 - Load fonts from profile-agnostic writable location. r=jfkthame (c9227268ff)
- Bug 1246889 - Correctly check whether hb_blob_create failed in ShareTableAndGetBlob. r=jfkthame (f8c62776be)
- Bug 1246834 - Fix memory reporting of nsFontFamily{List,Name}. r=jfkthame. (0535b8c110)
- Bug 1238134 P1 Provide a Response.cloneUnfiltered() method for chrome code to access internal Response state. r=ehsan (3dc25b1501)
- Bug 1238134 P2 Test chrome-only Response.cloneUnfiltered(). r=ehsan (3c307c4ec0)
- Bug 1100949 - wrap font info reads with structured exception handler. r=bas (2c2cacb05e)
- Bug 1241931 - On shutdown stop any ongoing loading of fonts; GDI in particular. r=jdaggett (057aae8cab)
- Bug 1154182 - enable native keybindings for graphene. r=billm (33e706a020)
- Bug 1167081 - Call PuppetWidget::Destroy() in its destructor. r=roc (58115c3029)
- Bug 1222662 - Disable cursor caching in the content process on Windows. r=aklotz (e760794ee2)
- Bug 1240891 - Silence warning from calling GetNativeData(NS_NATIVE_WINDOW). r=roc (d766a47f66)
- Bug 1248981 - Fix spelling error in nsMenuUtilsX.mm, a=tomcat (b93c16b961)
- Bug 1197925 - Use channel->Open2() in intl/hyphenation/hnjstdio.cpp (r=sicking) (2bf5dd3cd3)
- Bug 1248339 - fix header sort order of hal. r=gsvelto (01b61a2f5d)
- Bug 1232687: Add system-service interface to HAL, r=gsvelto (ab692e1508)
- Bug 1236762 - Simplify locking APIs for SharedSurface. - r=jrmuizel (901ae94a85)
505 lines
16 KiB
C++
505 lines
16 KiB
C++
/* -*- Mode: C++; tab-width: 20; 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 "CanvasClient.h"
|
|
|
|
#include "ClientCanvasLayer.h" // for ClientCanvasLayer
|
|
#include "GLContext.h" // for GLContext
|
|
#include "GLScreenBuffer.h" // for GLScreenBuffer
|
|
#include "ScopedGLHelpers.h"
|
|
#include "gfx2DGlue.h" // for ImageFormatToSurfaceFormat
|
|
#include "gfxPlatform.h" // for gfxPlatform
|
|
#include "GLReadTexImageHelper.h"
|
|
#include "mozilla/gfx/BaseSize.h" // for BaseSize
|
|
#include "mozilla/layers/BufferTexture.h"
|
|
#include "mozilla/layers/AsyncCanvasRenderer.h"
|
|
#include "mozilla/layers/CompositableForwarder.h"
|
|
#include "mozilla/layers/CompositorChild.h" // for CompositorChild
|
|
#include "mozilla/layers/GrallocTextureClient.h"
|
|
#include "mozilla/layers/LayersTypes.h"
|
|
#include "mozilla/layers/TextureClient.h" // for TextureClient, etc
|
|
#include "mozilla/layers/TextureClientOGL.h"
|
|
#include "nsAutoPtr.h" // for nsRefPtr
|
|
#include "nsDebug.h" // for printf_stderr, NS_ASSERTION
|
|
#include "nsXULAppAPI.h" // for XRE_GetProcessType, etc
|
|
#include "TextureClientSharedSurface.h"
|
|
#include "VRManagerChild.h"
|
|
|
|
using namespace mozilla::gfx;
|
|
using namespace mozilla::gl;
|
|
|
|
namespace mozilla {
|
|
namespace layers {
|
|
|
|
/* static */ already_AddRefed<CanvasClient>
|
|
CanvasClient::CreateCanvasClient(CanvasClientType aType,
|
|
CompositableForwarder* aForwarder,
|
|
TextureFlags aFlags)
|
|
{
|
|
switch (aType) {
|
|
case CanvasClientTypeShSurf:
|
|
return MakeAndAddRef<CanvasClientSharedSurface>(aForwarder, aFlags);
|
|
case CanvasClientAsync:
|
|
return MakeAndAddRef<CanvasClientBridge>(aForwarder, aFlags);
|
|
default:
|
|
return MakeAndAddRef<CanvasClient2D>(aForwarder, aFlags);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
CanvasClientBridge::UpdateAsync(AsyncCanvasRenderer* aRenderer)
|
|
{
|
|
if (!GetForwarder() || !mLayer || !aRenderer ||
|
|
!aRenderer->GetCanvasClient()) {
|
|
return;
|
|
}
|
|
|
|
uint64_t asyncID = aRenderer->GetCanvasClientAsyncID();
|
|
if (asyncID == 0 || mAsyncID == asyncID) {
|
|
return;
|
|
}
|
|
|
|
static_cast<ShadowLayerForwarder*>(GetForwarder())
|
|
->AttachAsyncCompositable(asyncID, mLayer);
|
|
mAsyncID = asyncID;
|
|
}
|
|
|
|
void
|
|
CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
|
{
|
|
AutoRemoveTexture autoRemove(this);
|
|
if (mBuffer &&
|
|
(mBuffer->IsImmutable() || mBuffer->GetSize() != aSize)) {
|
|
autoRemove.mTexture = mBuffer;
|
|
mBuffer = nullptr;
|
|
}
|
|
|
|
bool bufferCreated = false;
|
|
if (!mBuffer) {
|
|
bool isOpaque = (aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE);
|
|
gfxContentType contentType = isOpaque
|
|
? gfxContentType::COLOR
|
|
: gfxContentType::COLOR_ALPHA;
|
|
gfx::SurfaceFormat surfaceFormat
|
|
= gfxPlatform::GetPlatform()->Optimal2DFormatForContent(contentType);
|
|
TextureFlags flags = TextureFlags::DEFAULT;
|
|
if (mTextureFlags & TextureFlags::ORIGIN_BOTTOM_LEFT) {
|
|
flags |= TextureFlags::ORIGIN_BOTTOM_LEFT;
|
|
}
|
|
|
|
mBuffer = CreateTextureClientForCanvas(surfaceFormat, aSize, flags, aLayer);
|
|
if (!mBuffer) {
|
|
NS_WARNING("Failed to allocate the TextureClient");
|
|
return;
|
|
}
|
|
MOZ_ASSERT(mBuffer->CanExposeDrawTarget());
|
|
|
|
bufferCreated = true;
|
|
}
|
|
|
|
bool updated = false;
|
|
{
|
|
TextureClientAutoLock autoLock(mBuffer, OpenMode::OPEN_WRITE_ONLY);
|
|
if (!autoLock.Succeeded()) {
|
|
mBuffer = nullptr;
|
|
return;
|
|
}
|
|
|
|
RefPtr<DrawTarget> target = mBuffer->BorrowDrawTarget();
|
|
if (target) {
|
|
aLayer->UpdateTarget(target);
|
|
updated = true;
|
|
}
|
|
}
|
|
|
|
if (bufferCreated && !AddTextureClient(mBuffer)) {
|
|
mBuffer = nullptr;
|
|
return;
|
|
}
|
|
|
|
if (updated) {
|
|
AutoTArray<CompositableForwarder::TimedTextureClient,1> textures;
|
|
CompositableForwarder::TimedTextureClient* t = textures.AppendElement();
|
|
t->mTextureClient = mBuffer;
|
|
t->mPictureRect = nsIntRect(nsIntPoint(0, 0), mBuffer->GetSize());
|
|
t->mFrameID = mFrameID;
|
|
t->mInputFrameID = VRManagerChild::Get()->GetInputFrameID();
|
|
GetForwarder()->UseTextures(this, textures);
|
|
mBuffer->SyncWithObject(GetForwarder()->GetSyncObject());
|
|
}
|
|
}
|
|
|
|
already_AddRefed<TextureClient>
|
|
CanvasClient2D::CreateTextureClientForCanvas(gfx::SurfaceFormat aFormat,
|
|
gfx::IntSize aSize,
|
|
TextureFlags aFlags,
|
|
ClientCanvasLayer* aLayer)
|
|
{
|
|
if (aLayer->IsGLLayer()) {
|
|
// We want a cairo backend here as we don't want to be copying into
|
|
// an accelerated backend and we like LockBits to work. This is currently
|
|
// the most effective way to make this work.
|
|
return TextureClient::CreateForRawBufferAccess(GetForwarder(),
|
|
aFormat, aSize, BackendType::CAIRO,
|
|
mTextureFlags | aFlags);
|
|
}
|
|
|
|
#ifdef XP_WIN
|
|
return CreateTextureClientForDrawing(aFormat, aSize, BackendSelector::Canvas, aFlags);
|
|
#else
|
|
// XXX - We should use CreateTextureClientForDrawing, but we first need
|
|
// to use double buffering.
|
|
gfx::BackendType backend = gfxPlatform::GetPlatform()->GetPreferredCanvasBackend();
|
|
return TextureClient::CreateForRawBufferAccess(GetForwarder(),
|
|
aFormat, aSize, backend,
|
|
mTextureFlags | aFlags);
|
|
#endif
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
CanvasClientSharedSurface::CanvasClientSharedSurface(CompositableForwarder* aLayerForwarder,
|
|
TextureFlags aFlags)
|
|
: CanvasClient(aLayerForwarder, aFlags)
|
|
{ }
|
|
|
|
CanvasClientSharedSurface::~CanvasClientSharedSurface()
|
|
{
|
|
ClearSurfaces();
|
|
}
|
|
|
|
////////////////////////////////////////
|
|
// Readback
|
|
|
|
// For formats compatible with R8G8B8A8.
|
|
static inline void SwapRB_R8G8B8A8(uint8_t* pixel) {
|
|
// [RR, GG, BB, AA]
|
|
Swap(pixel[0], pixel[2]);
|
|
}
|
|
|
|
class TexClientFactory
|
|
{
|
|
ISurfaceAllocator* const mAllocator;
|
|
const bool mHasAlpha;
|
|
const gfx::IntSize mSize;
|
|
const gfx::BackendType mBackendType;
|
|
const TextureFlags mBaseTexFlags;
|
|
const LayersBackend mLayersBackend;
|
|
|
|
public:
|
|
TexClientFactory(ISurfaceAllocator* allocator, bool hasAlpha,
|
|
const gfx::IntSize& size, gfx::BackendType backendType,
|
|
TextureFlags baseTexFlags, LayersBackend layersBackend)
|
|
: mAllocator(allocator)
|
|
, mHasAlpha(hasAlpha)
|
|
, mSize(size)
|
|
, mBackendType(backendType)
|
|
, mBaseTexFlags(baseTexFlags)
|
|
, mLayersBackend(layersBackend)
|
|
{
|
|
}
|
|
|
|
protected:
|
|
already_AddRefed<TextureClient> Create(gfx::SurfaceFormat format) {
|
|
return TextureClient::CreateForRawBufferAccess(mAllocator, format,
|
|
mSize, mBackendType,
|
|
mBaseTexFlags);
|
|
}
|
|
|
|
public:
|
|
already_AddRefed<TextureClient> CreateB8G8R8AX8() {
|
|
gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::B8G8R8A8
|
|
: gfx::SurfaceFormat::B8G8R8X8;
|
|
return Create(format);
|
|
}
|
|
|
|
already_AddRefed<TextureClient> CreateR8G8B8AX8() {
|
|
RefPtr<TextureClient> ret;
|
|
|
|
bool areRGBAFormatsBroken = mLayersBackend == LayersBackend::LAYERS_BASIC;
|
|
if (!areRGBAFormatsBroken) {
|
|
gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8
|
|
: gfx::SurfaceFormat::R8G8B8X8;
|
|
ret = Create(format);
|
|
}
|
|
|
|
if (!ret) {
|
|
ret = CreateB8G8R8AX8();
|
|
if (ret) {
|
|
ret->AddFlags(TextureFlags::RB_SWAPPED);
|
|
}
|
|
}
|
|
|
|
return ret.forget();
|
|
}
|
|
};
|
|
|
|
static already_AddRefed<TextureClient>
|
|
TexClientFromReadback(SharedSurface* src, ISurfaceAllocator* allocator,
|
|
TextureFlags baseFlags, LayersBackend layersBackend)
|
|
{
|
|
auto backendType = gfx::BackendType::CAIRO;
|
|
TexClientFactory factory(allocator, src->mHasAlpha, src->mSize, backendType,
|
|
baseFlags, layersBackend);
|
|
|
|
RefPtr<TextureClient> texClient;
|
|
|
|
{
|
|
gl::ScopedReadbackFB autoReadback(src);
|
|
|
|
// We have a source FB, now we need a format.
|
|
GLenum destFormat = LOCAL_GL_BGRA;
|
|
GLenum destType = LOCAL_GL_UNSIGNED_BYTE;
|
|
GLenum readFormat;
|
|
GLenum readType;
|
|
|
|
// We actually don't care if they match, since we can handle
|
|
// any read{Format,Type} we get.
|
|
auto gl = src->mGL;
|
|
GetActualReadFormats(gl, destFormat, destType, &readFormat, &readType);
|
|
|
|
MOZ_ASSERT(readFormat == LOCAL_GL_RGBA ||
|
|
readFormat == LOCAL_GL_BGRA);
|
|
MOZ_ASSERT(readType == LOCAL_GL_UNSIGNED_BYTE);
|
|
|
|
// With a format and type, we can create texClient.
|
|
if (readFormat == LOCAL_GL_BGRA &&
|
|
readType == LOCAL_GL_UNSIGNED_BYTE)
|
|
{
|
|
// 0xAARRGGBB
|
|
// In Lendian: [BB, GG, RR, AA]
|
|
texClient = factory.CreateB8G8R8AX8();
|
|
|
|
} else if (readFormat == LOCAL_GL_RGBA &&
|
|
readType == LOCAL_GL_UNSIGNED_BYTE)
|
|
{
|
|
// [RR, GG, BB, AA]
|
|
texClient = factory.CreateR8G8B8AX8();
|
|
} else {
|
|
MOZ_CRASH("GFX: Bad `read{Format,Type}`.");
|
|
}
|
|
|
|
MOZ_ASSERT(texClient);
|
|
if (!texClient)
|
|
return nullptr;
|
|
|
|
// With a texClient, we can lock for writing.
|
|
TextureClientAutoLock autoLock(texClient, OpenMode::OPEN_WRITE);
|
|
DebugOnly<bool> succeeded = autoLock.Succeeded();
|
|
MOZ_ASSERT(succeeded, "texture should have locked");
|
|
|
|
MappedTextureData mapped;
|
|
texClient->BorrowMappedData(mapped);
|
|
|
|
// ReadPixels from the current FB into mapped.data.
|
|
auto width = src->mSize.width;
|
|
auto height = src->mSize.height;
|
|
|
|
{
|
|
ScopedPackAlignment autoAlign(gl, 4);
|
|
|
|
MOZ_ASSERT(mapped.stride/4 == mapped.size.width);
|
|
gl->raw_fReadPixels(0, 0, width, height, readFormat, readType, mapped.data);
|
|
}
|
|
|
|
// RB_SWAPPED doesn't work with D3D11. (bug 1051010)
|
|
// RB_SWAPPED doesn't work with Basic. (bug ???????)
|
|
// RB_SWAPPED doesn't work with D3D9. (bug ???????)
|
|
bool layersNeedsManualSwap = layersBackend == LayersBackend::LAYERS_BASIC ||
|
|
layersBackend == LayersBackend::LAYERS_D3D9 ||
|
|
layersBackend == LayersBackend::LAYERS_D3D11;
|
|
if (texClient->HasFlags(TextureFlags::RB_SWAPPED) &&
|
|
layersNeedsManualSwap)
|
|
{
|
|
size_t pixels = width * height;
|
|
uint8_t* itr = mapped.data;
|
|
for (size_t i = 0; i < pixels; i++) {
|
|
SwapRB_R8G8B8A8(itr);
|
|
itr += 4;
|
|
}
|
|
|
|
texClient->RemoveFlags(TextureFlags::RB_SWAPPED);
|
|
}
|
|
}
|
|
|
|
return texClient.forget();
|
|
}
|
|
|
|
////////////////////////////////////////
|
|
|
|
static already_AddRefed<SharedSurfaceTextureClient>
|
|
CloneSurface(gl::SharedSurface* src, gl::SurfaceFactory* factory)
|
|
{
|
|
RefPtr<SharedSurfaceTextureClient> dest = factory->NewTexClient(src->mSize);
|
|
if (!dest) {
|
|
return nullptr;
|
|
}
|
|
|
|
gl::SharedSurface* destSurf = dest->Surf();
|
|
|
|
destSurf->ProducerAcquire();
|
|
SharedSurface::ProdCopy(src, dest->Surf(), factory);
|
|
destSurf->ProducerRelease();
|
|
|
|
return dest.forget();
|
|
}
|
|
|
|
void
|
|
CanvasClientSharedSurface::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
|
{
|
|
Renderer renderer;
|
|
renderer.construct<ClientCanvasLayer*>(aLayer);
|
|
UpdateRenderer(aSize, renderer);
|
|
}
|
|
|
|
void
|
|
CanvasClientSharedSurface::UpdateAsync(AsyncCanvasRenderer* aRenderer)
|
|
{
|
|
Renderer renderer;
|
|
renderer.construct<AsyncCanvasRenderer*>(aRenderer);
|
|
UpdateRenderer(aRenderer->GetSize(), renderer);
|
|
}
|
|
|
|
void
|
|
CanvasClientSharedSurface::UpdateRenderer(gfx::IntSize aSize, Renderer& aRenderer)
|
|
{
|
|
GLContext* gl = nullptr;
|
|
ClientCanvasLayer* layer = nullptr;
|
|
AsyncCanvasRenderer* asyncRenderer = nullptr;
|
|
if (aRenderer.constructed<ClientCanvasLayer*>()) {
|
|
layer = aRenderer.ref<ClientCanvasLayer*>();
|
|
gl = layer->mGLContext;
|
|
} else {
|
|
asyncRenderer = aRenderer.ref<AsyncCanvasRenderer*>();
|
|
gl = asyncRenderer->mGLContext;
|
|
}
|
|
gl->MakeCurrent();
|
|
|
|
RefPtr<TextureClient> newFront;
|
|
|
|
if (layer && layer->mGLFrontbuffer) {
|
|
mShSurfClient = CloneSurface(layer->mGLFrontbuffer.get(), layer->mFactory.get());
|
|
if (!mShSurfClient) {
|
|
gfxCriticalError() << "Invalid canvas front buffer";
|
|
return;
|
|
}
|
|
} else {
|
|
mShSurfClient = gl->Screen()->Front();
|
|
if (!mShSurfClient) {
|
|
return;
|
|
}
|
|
}
|
|
MOZ_ASSERT(mShSurfClient);
|
|
|
|
newFront = mShSurfClient;
|
|
|
|
SharedSurface* surf = mShSurfClient->Surf();
|
|
|
|
// Readback if needed.
|
|
mReadbackClient = nullptr;
|
|
|
|
auto forwarder = GetForwarder();
|
|
|
|
bool needsReadback = (surf->mType == SharedSurfaceType::Basic);
|
|
if (needsReadback) {
|
|
TextureFlags flags = TextureFlags::IMMUTABLE;
|
|
|
|
CompositableForwarder* shadowForwarder = nullptr;
|
|
if (layer) {
|
|
flags |= layer->Flags();
|
|
shadowForwarder = layer->ClientManager()->AsShadowForwarder();
|
|
} else {
|
|
MOZ_ASSERT(asyncRenderer);
|
|
flags |= mTextureFlags;
|
|
shadowForwarder = GetForwarder();
|
|
}
|
|
|
|
auto layersBackend = shadowForwarder->GetCompositorBackendType();
|
|
mReadbackClient = TexClientFromReadback(surf, forwarder, flags, layersBackend);
|
|
|
|
if (asyncRenderer) {
|
|
// Above codes will readback the GLContext to mReadbackClient
|
|
// in order to send frame to compositor. We copy from this
|
|
// TextureClient directly by calling CopyFromTextureClient().
|
|
// Therefore, if main-thread want the content of GLContext,
|
|
// it don't have to readback it again.
|
|
asyncRenderer->CopyFromTextureClient(mReadbackClient);
|
|
}
|
|
|
|
newFront = mReadbackClient;
|
|
} else {
|
|
mReadbackClient = nullptr;
|
|
}
|
|
|
|
MOZ_ASSERT(newFront);
|
|
if (!newFront) {
|
|
// May happen in a release build in case of memory pressure.
|
|
gfxCriticalError() << "Failed to allocate a TextureClient for SharedSurface Canvas. Size: " << aSize;
|
|
return;
|
|
}
|
|
|
|
mNewFront = newFront;
|
|
}
|
|
|
|
void
|
|
CanvasClientSharedSurface::Updated()
|
|
{
|
|
if (!mNewFront) {
|
|
return;
|
|
}
|
|
|
|
auto forwarder = GetForwarder();
|
|
|
|
#ifndef MOZ_WIDGET_GONK
|
|
if (mFront) {
|
|
if (mFront->GetFlags() & TextureFlags::RECYCLE) {
|
|
mFront->WaitForCompositorRecycle();
|
|
}
|
|
}
|
|
#else
|
|
// AutoRemoveTexture does the followings.
|
|
// - Ensure to deliver FenceHandle from TextureHost to TextureClient, before
|
|
// next TextureClient usage.
|
|
// - Control TextureClient's recycling timing.
|
|
// - Call RemoveTexture() after newFront's UseTextures() call.
|
|
// It could improve performance of Host side's EGL handling on gonk
|
|
AutoRemoveTexture autoRemove(this);
|
|
if (mFront && mFront != mNewFront) {
|
|
autoRemove.mTexture = mFront;
|
|
}
|
|
#endif
|
|
|
|
mFront = mNewFront;
|
|
mNewFront = nullptr;
|
|
|
|
// Add the new TexClient.
|
|
MOZ_ALWAYS_TRUE( AddTextureClient(mFront) );
|
|
|
|
AutoTArray<CompositableForwarder::TimedTextureClient,1> textures;
|
|
CompositableForwarder::TimedTextureClient* t = textures.AppendElement();
|
|
t->mTextureClient = mFront;
|
|
t->mPictureRect = nsIntRect(nsIntPoint(0, 0), mFront->GetSize());
|
|
t->mFrameID = mFrameID;
|
|
// XXX TODO - This reference to VRManagerChild will be moved with the
|
|
// implementation of the WebVR 1.0 API, which will enable
|
|
// the inputFrameID to be passed through Javascript with
|
|
// the new VRDisplay API.
|
|
t->mInputFrameID = VRManagerChild::Get()->GetInputFrameID();
|
|
forwarder->UseTextures(this, textures);
|
|
}
|
|
|
|
void
|
|
CanvasClientSharedSurface::ClearSurfaces()
|
|
{
|
|
mFront = nullptr;
|
|
mNewFront = nullptr;
|
|
mShSurfClient = nullptr;
|
|
mReadbackClient = nullptr;
|
|
}
|
|
|
|
} // namespace layers
|
|
} // namespace mozilla
|