Backed out changeset c4ecea1452e9 (bug 947781)

This commit is contained in:
Ed Morley 2014-07-30 14:54:08 +01:00
Родитель f6dad403d3
Коммит 46d9238c0a
9 изменённых файлов: 0 добавлений и 304 удалений

Просмотреть файл

@ -54,12 +54,6 @@ DIBTextureClient::Unlock()
{
MOZ_ASSERT(mIsLocked, "Unlocked called while the texture is not locked!");
if (mDrawTarget) {
if (mReadbackSink) {
RefPtr<SourceSurface> snapshot = mDrawTarget->Snapshot();
RefPtr<DataSourceSurface> dataSurf = snapshot->GetDataSurface();
mReadbackSink->ProcessReadback(dataSurf);
}
mDrawTarget->Flush();
mDrawTarget = nullptr;
}

Просмотреть файл

@ -731,12 +731,6 @@ BufferTextureClient::Unlock()
// reference remains by the time Unlock() is called.
MOZ_ASSERT(mDrawTarget->refCount() == 1);
if (mReadbackSink) {
RefPtr<SourceSurface> snapshot = mDrawTarget->Snapshot();
RefPtr<DataSourceSurface> dataSurf = snapshot->GetDataSurface();
mReadbackSink->ProcessReadback(dataSurf);
}
mDrawTarget->Flush();
mDrawTarget = nullptr;
}

Просмотреть файл

@ -89,24 +89,6 @@ public:
StereoMode aStereoMode) = 0;
};
/**
* This class may be used to asynchronously receive an update when the content
* drawn to this texture client is available for reading in CPU memory. This
* can only be used on texture clients that support draw target creation.
*/
class TextureReadbackSink
{
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TextureReadbackSink)
public:
/**
* Callback function to implement in order to receive a DataSourceSurface
* containing the data read back from the texture client. This will always
* be called on the main thread, and this may not hold on to the
* DataSourceSurface beyond the execution of this function.
*/
virtual void ProcessReadback(gfx::DataSourceSurface *aSourceSurface) = 0;
};
/**
* TextureClient is a thin abstraction over texture data that need to be shared
* between the content process and the compositor process. It is the
@ -391,15 +373,6 @@ public:
mWasteTracker.Update(aWasteArea, BytesPerPixel(GetFormat()));
}
/**
* This sets the readback sink that this texture is to use. This will
* receive the data for this texture as soon as it becomes available after
* texture unlock.
*/
virtual void SetReadbackSink(TextureReadbackSink* aReadbackSink) {
mReadbackSink = aReadbackSink;
}
private:
/**
* Called once, just before the destructor.
@ -448,8 +421,6 @@ protected:
bool mShared;
bool mValid;
RefPtr<TextureReadbackSink> mReadbackSink;
friend class TextureChild;
friend class RemoveTextureFromCompositableTracker;
friend void TestTextureClientSurface(TextureClient*, gfxImageSurface*);

Просмотреть файл

@ -1,159 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* 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 "ReadbackManagerD3D11.h"
#include "ReadbackProcessor.h"
#include "ReadbackLayer.h"
#include "mozilla/layers/TextureClient.h"
#include "mozilla/gfx/2D.h"
#include "nsIThread.h"
#include "nsThreadUtils.h"
namespace mozilla {
using namespace gfx;
namespace layers {
// Structure that contains the information required to execute a readback task,
// the only member accessed off the main thread here is mReadbackTexture. Since
// mSink may be released only on the main thread this object should always be
// destroyed on the main thread!
struct ReadbackTask {
// The texture that we copied the contents of the thebeslayer to.
nsRefPtr<ID3D10Texture2D> mReadbackTexture;
// The sink that we're trying to read back to.
RefPtr<TextureReadbackSink> mSink;
};
// This class is created and dispatched from the Readback thread but it must be
// destroyed by the main thread.
class ReadbackResultWriterD3D11 MOZ_FINAL : public nsIRunnable
{
~ReadbackResultWriterD3D11() {}
NS_DECL_THREADSAFE_ISUPPORTS
public:
ReadbackResultWriterD3D11(ReadbackTask *aTask) : mTask(aTask) {}
NS_IMETHODIMP Run()
{
D3D10_TEXTURE2D_DESC desc;
mTask->mReadbackTexture->GetDesc(&desc);
D3D10_MAPPED_TEXTURE2D mappedTex;
// We know this map will immediately succeed, as we've already mapped this
// copied data on our task thread.
HRESULT hr = mTask->mReadbackTexture->Map(0, D3D10_MAP_READ, 0, &mappedTex);
if (FAILED(hr)) {
mTask->mSink->ProcessReadback(nullptr);
}
{
RefPtr<DataSourceSurface> surf =
Factory::CreateWrappingDataSourceSurface((uint8_t*)mappedTex.pData, mappedTex.RowPitch,
IntSize(desc.Width, desc.Height),
SurfaceFormat::B8G8R8X8);
mTask->mSink->ProcessReadback(surf);
MOZ_ASSERT(surf->hasOneRef());
}
mTask->mReadbackTexture->Unmap(0);
return NS_OK;
}
private:
nsAutoPtr<ReadbackTask> mTask;
};
NS_IMPL_ISUPPORTS(ReadbackResultWriterD3D11, nsIRunnable)
static DWORD WINAPI StartTaskThread(void *aManager)
{
static_cast<ReadbackManagerD3D11*>(aManager)->ProcessTasks();
return 0;
}
ReadbackManagerD3D11::ReadbackManagerD3D11()
: mRefCnt(0)
{
::InitializeCriticalSection(&mTaskMutex);
mShutdownEvent = ::CreateEventA(nullptr, FALSE, FALSE, nullptr);
mTaskSemaphore = ::CreateSemaphoreA(nullptr, 0, 1000000, nullptr);
mTaskThread = ::CreateThread(nullptr, 0, StartTaskThread, this, 0, 0);
}
ReadbackManagerD3D11::~ReadbackManagerD3D11()
{
::SetEvent(mShutdownEvent);
// This shouldn't take longer than 5 seconds, if it does we're going to choose
// to leak the thread and its synchronisation in favor of crashing or freezing
DWORD result = ::WaitForSingleObject(mTaskThread, 5000);
if (result != WAIT_TIMEOUT) {
::DeleteCriticalSection(&mTaskMutex);
::CloseHandle(mShutdownEvent);
::CloseHandle(mTaskSemaphore);
::CloseHandle(mTaskThread);
} else {
NS_RUNTIMEABORT("ReadbackManager: Task thread did not shutdown in 5 seconds.");
}
}
void
ReadbackManagerD3D11::PostTask(ID3D10Texture2D *aTexture, TextureReadbackSink* aSink)
{
ReadbackTask *task = new ReadbackTask;
task->mReadbackTexture = aTexture;
task->mSink = aSink;
::EnterCriticalSection(&mTaskMutex);
mPendingReadbackTasks.AppendElement(task);
::LeaveCriticalSection(&mTaskMutex);
::ReleaseSemaphore(mTaskSemaphore, 1, nullptr);
}
void
ReadbackManagerD3D11::ProcessTasks()
{
HANDLE handles[] = { mTaskSemaphore, mShutdownEvent };
while (true) {
DWORD result = ::WaitForMultipleObjects(2, handles, FALSE, INFINITE);
if (result != WAIT_OBJECT_0) {
return;
}
::EnterCriticalSection(&mTaskMutex);
if (mPendingReadbackTasks.Length() == 0) {
NS_RUNTIMEABORT("Trying to read from an empty array, bad bad bad");
}
ReadbackTask *nextReadbackTask = mPendingReadbackTasks[0].forget();
mPendingReadbackTasks.RemoveElementAt(0);
::LeaveCriticalSection(&mTaskMutex);
// We want to block here until the texture contents are available, the
// easiest thing is to simply map and unmap.
D3D10_MAPPED_TEXTURE2D mappedTex;
nextReadbackTask->mReadbackTexture->Map(0, D3D10_MAP_READ, 0, &mappedTex);
nextReadbackTask->mReadbackTexture->Unmap(0);
// We can only send the update to the sink on the main thread, so post an
// event there to do so. Ownership of the task is passed from
// mPendingReadbackTasks to ReadbackResultWriter here.
nsCOMPtr<nsIThread> thread = do_GetMainThread();
thread->Dispatch(new ReadbackResultWriterD3D11(nextReadbackTask),
nsIEventTarget::DISPATCH_NORMAL);
}
}
}
}

Просмотреть файл

@ -1,64 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* 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/. */
#ifndef GFX_READBACKMANAGERD3D11_H
#define GFX_READBACKMANAGERD3D11_H
#include <windows.h>
#include <d3d10_1.h>
#include "nsTArray.h"
#include "nsAutoPtr.h"
namespace mozilla {
namespace layers {
class TextureReadbackSink;
struct ReadbackTask;
class ReadbackManagerD3D11 MOZ_FINAL
{
NS_INLINE_DECL_REFCOUNTING(ReadbackManagerD3D11)
public:
ReadbackManagerD3D11();
~ReadbackManagerD3D11();
/**
* Tell the readback manager to post a readback task.
*
* @param aTexture D3D10_USAGE_STAGING texture that will contain the data that
* was readback.
* @param aSink TextureReadbackSink that the resulting DataSourceSurface
* should be dispatched to.
*/
void PostTask(ID3D10Texture2D* aTexture, TextureReadbackSink* aSink);
private:
friend DWORD WINAPI StartTaskThread(void *aManager);
void ProcessTasks();
// The invariant maintained by |mTaskSemaphore| is that the readback thread
// will awaken from WaitForMultipleObjects() at least once per readback
// task enqueued by the main thread. Since the readback thread processes
// exactly one task per wakeup (with one exception), no tasks are lost. The
// exception is when the readback thread is shut down, which orphans the
// remaining tasks, on purpose.
HANDLE mTaskSemaphore;
// Event signaled when the task thread should shutdown
HANDLE mShutdownEvent;
// Handle to the task thread
HANDLE mTaskThread;
// FiFo list of readback tasks that are to be executed. Access is synchronized
// by mTaskMutex.
CRITICAL_SECTION mTaskMutex;
nsTArray<nsAutoPtr<ReadbackTask>> mPendingReadbackTasks;
};
}
}
#endif /* GFX_READBACKMANAGERD3D11_H */

Просмотреть файл

@ -11,7 +11,6 @@
#include "gfxWindowsPlatform.h"
#include "gfxD2DSurface.h"
#include "gfx2DGlue.h"
#include "ReadbackManagerD3D11.h"
namespace mozilla {
@ -250,28 +249,6 @@ TextureClientD3D11::Unlock()
mDrawTarget->Flush();
}
if (mReadbackSink) {
ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
D3D10_TEXTURE2D_DESC desc;
mTexture->GetDesc(&desc);
desc.BindFlags = 0;
desc.Usage = D3D10_USAGE_STAGING;
desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
desc.MiscFlags = 0;
RefPtr<ID3D10Texture2D> tex;
HRESULT hr = device->CreateTexture2D(&desc, nullptr, byRef(tex));
if (SUCCEEDED(hr)) {
device->CopyResource(tex, mTexture);
gfxWindowsPlatform::GetPlatform()->GetReadbackManager()->PostTask(tex, mReadbackSink);
} else {
mReadbackSink->ProcessReadback(nullptr);
}
}
// The DrawTarget is created only once, and is only usable between calls
// to Lock and Unlock.
UnlockD3DTexture(mTexture.get());

Просмотреть файл

@ -80,7 +80,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
]
EXPORTS.mozilla.layers += [
'd3d11/CompositorD3D11.h',
'd3d11/ReadbackManagerD3D11.h',
'd3d11/TextureD3D11.h',
'ipc/ShadowLayerUtilsD3D10.h',
]
@ -97,7 +96,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
]
SOURCES += [
'd3d11/CompositorD3D11.cpp',
'd3d11/ReadbackManagerD3D11.cpp',
]
EXPORTS.gfxipc += [

Просмотреть файл

@ -32,7 +32,6 @@
#include "mozilla/layers/CompositorParent.h" // for CompositorParent::IsInCompositorThread
#include "DeviceManagerD3D9.h"
#include "mozilla/layers/ReadbackManagerD3D11.h"
#include "WinUtils.h"
@ -1392,16 +1391,6 @@ gfxWindowsPlatform::GetD3D11Device()
return mD3D11Device;
}
ReadbackManagerD3D11*
gfxWindowsPlatform::GetReadbackManager()
{
if (!mD3D11ReadbackManager) {
mD3D11ReadbackManager = new ReadbackManagerD3D11();
}
return mD3D11ReadbackManager;
}
bool
gfxWindowsPlatform::IsOptimus()
{

Просмотреть файл

@ -46,7 +46,6 @@
namespace mozilla {
namespace layers {
class DeviceManagerD3D9;
class ReadbackManagerD3D11;
}
}
struct IDirect3DDevice9;
@ -257,8 +256,6 @@ public:
#endif
ID3D11Device *GetD3D11Device();
mozilla::layers::ReadbackManagerD3D11* GetReadbackManager();
static bool IsOptimus();
protected:
@ -287,7 +284,6 @@ private:
nsRefPtr<mozilla::layers::DeviceManagerD3D9> mDeviceManager;
mozilla::RefPtr<ID3D11Device> mD3D11Device;
bool mD3D11DeviceInitialized;
mozilla::RefPtr<mozilla::layers::ReadbackManagerD3D11> mD3D11ReadbackManager;
virtual void GetPlatformCMSOutputProfile(void* &mem, size_t &size);