Commit e1aa9219 by Geoff Lang Committed by Commit Bot

Create a new DeviceImpl each time one is requested from a DisplayImpl.

This makes sure that the Device to DeviceImpl ratio is always 1:1 and avoids any potential double-deletion or unexpected deletion of DeviceImpl objects. BUG=742034 Change-Id: I778068ccd09b7478d3683123456062b94be242a1 Reviewed-on: https://chromium-review.googlesource.com/854627 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org>
parent ea22b7a5
......@@ -43,7 +43,7 @@ static DeviceSet *GetDeviceSet()
}
// Static factory methods
egl::Error Device::CreateDevice(void *devicePointer, EGLint deviceType, Device **outDevice)
egl::Error Device::CreateDevice(EGLint deviceType, void *nativeDevice, Device **outDevice)
{
*outDevice = nullptr;
......@@ -52,10 +52,12 @@ egl::Error Device::CreateDevice(void *devicePointer, EGLint deviceType, Device *
#if defined(ANGLE_ENABLE_D3D11)
if (deviceType == EGL_D3D11_DEVICE_ANGLE)
{
newDeviceImpl.reset(new rx::DeviceD3D(deviceType, devicePointer));
newDeviceImpl.reset(new rx::DeviceD3D(deviceType, nativeDevice));
}
#endif
// Note that creating an EGL device from inputted D3D9 parameters isn't currently supported
if (newDeviceImpl == nullptr)
{
return EglBadAttribute();
......@@ -63,15 +65,7 @@ egl::Error Device::CreateDevice(void *devicePointer, EGLint deviceType, Device *
ANGLE_TRY(newDeviceImpl->initialize());
*outDevice = new Device(nullptr, newDeviceImpl.release());
GetDeviceSet()->insert(*outDevice);
return NoError();
}
egl::Error Device::CreateDevice(Display *owningDisplay, rx::DeviceImpl *impl, Device **outDevice)
{
*outDevice = new Device(owningDisplay, impl);
GetDeviceSet()->insert(*outDevice);
return NoError();
}
......@@ -84,6 +78,8 @@ bool Device::IsValidDevice(Device *device)
Device::Device(Display *owningDisplay, rx::DeviceImpl *impl)
: mOwningDisplay(owningDisplay), mImplementation(impl)
{
ASSERT(GetDeviceSet()->find(this) == GetDeviceSet()->end());
GetDeviceSet()->insert(this);
initDeviceExtensions();
}
......@@ -91,12 +87,6 @@ Device::~Device()
{
ASSERT(GetDeviceSet()->find(this) != GetDeviceSet()->end());
GetDeviceSet()->erase(this);
if (!mOwningDisplay)
{
// If the device isn't externally sourced then it is up to the renderer to delete the impl
SafeDelete(mImplementation);
}
}
Error Device::getDevice(EGLAttrib *value)
......
......@@ -14,6 +14,8 @@
#include "libANGLE/Error.h"
#include "libANGLE/Display.h"
#include <memory>
namespace rx
{
class DeviceImpl;
......@@ -24,6 +26,7 @@ namespace egl
class Device final : angle::NonCopyable
{
public:
Device(Display *owningDisplay, rx::DeviceImpl *impl);
virtual ~Device();
Error getDevice(EGLAttrib *value);
......@@ -33,21 +36,16 @@ class Device final : angle::NonCopyable
const DeviceExtensions &getExtensions() const;
const std::string &getExtensionString() const;
rx::DeviceImpl *getImplementation() { return mImplementation; }
static egl::Error CreateDevice(void *devicePointer, EGLint deviceType, Device **outDevice);
static egl::Error CreateDevice(Display *owningDisplay,
rx::DeviceImpl *impl,
Device **outDevice);
rx::DeviceImpl *getImplementation() { return mImplementation.get(); }
static egl::Error CreateDevice(EGLint deviceType, void *nativeDevice, Device **outDevice);
static bool IsValidDevice(Device *device);
private:
Device(Display *owningDisplay, rx::DeviceImpl *impl);
void initDeviceExtensions();
Display *mOwningDisplay;
rx::DeviceImpl *mImplementation;
std::unique_ptr<rx::DeviceImpl> mImplementation;
DeviceExtensions mDeviceExtensions;
std::string mDeviceExtensionString;
......
......@@ -25,11 +25,12 @@
#include "common/utilities.h"
#include "libANGLE/Context.h"
#include "libANGLE/Device.h"
#include "libANGLE/histogram_macros.h"
#include "libANGLE/Image.h"
#include "libANGLE/Surface.h"
#include "libANGLE/Stream.h"
#include "libANGLE/ResourceManager.h"
#include "libANGLE/Stream.h"
#include "libANGLE/Surface.h"
#include "libANGLE/histogram_macros.h"
#include "libANGLE/renderer/DeviceImpl.h"
#include "libANGLE/renderer/DisplayImpl.h"
#include "libANGLE/renderer/ImageImpl.h"
#include "third_party/trace_event/trace_event.h"
......@@ -483,9 +484,10 @@ Error Display::initialize()
{
if (mDisplayExtensions.deviceQuery)
{
rx::DeviceImpl *impl = nullptr;
ANGLE_TRY(mImplementation->getDevice(&impl));
ANGLE_TRY(Device::CreateDevice(this, impl, &mDevice));
std::unique_ptr<rx::DeviceImpl> impl(mImplementation->createDevice());
ASSERT(impl != nullptr);
ANGLE_TRY(impl->initialize());
mDevice = new Device(this, impl.release());
}
else
{
......
......@@ -68,7 +68,7 @@ class DisplayImpl : public EGLImplFactory
virtual std::string getVendorString() const = 0;
virtual egl::Error getDevice(DeviceImpl **device) = 0;
virtual DeviceImpl *createDevice() = 0;
virtual egl::Error waitClient(const gl::Context *context) const = 0;
virtual egl::Error waitNative(const gl::Context *context, EGLint engine) const = 0;
......
......@@ -195,9 +195,9 @@ ImageImpl *DisplayD3D::createImage(const egl::ImageState &state,
return new EGLImageD3D(state, target, attribs, mRenderer);
}
egl::Error DisplayD3D::getDevice(DeviceImpl **device)
DeviceImpl *DisplayD3D::createDevice()
{
return mRenderer->getEGLDevice(device);
return mRenderer->createEGLDevice();
}
ContextImpl *DisplayD3D::createContext(const gl::ContextState &state)
......
......@@ -60,7 +60,7 @@ class DisplayD3D : public DisplayImpl
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const override;
egl::Error getDevice(DeviceImpl **device) override;
DeviceImpl *createDevice() override;
std::string getVendorString() const override;
......
......@@ -278,7 +278,7 @@ class RendererD3D : public BufferFactoryD3D, public MultisampleTextureInitialize
const float clearDepthValue,
const unsigned int clearStencilValue) = 0;
virtual egl::Error getEGLDevice(DeviceImpl **device) = 0;
virtual DeviceImpl *createEGLDevice() = 0;
bool presentPathFastEnabled() const { return mPresentPathFastEnabled; }
......
......@@ -473,7 +473,6 @@ Renderer11::Renderer11(egl::Display *display)
mDxgiModule = nullptr;
mDCompModule = nullptr;
mCreatedWithDeviceEXT = false;
mEGLDevice = nullptr;
mDevice = nullptr;
mDeviceContext = nullptr;
......@@ -556,10 +555,9 @@ Renderer11::Renderer11(egl::Display *display)
mCreateDebugDevice = ShouldUseDebugLayers(attributes);
}
else if (display->getPlatform() == EGL_PLATFORM_DEVICE_EXT)
else if (mDisplay->getPlatform() == EGL_PLATFORM_DEVICE_EXT)
{
mEGLDevice = GetImplAs<DeviceD3D>(display->getDevice());
ASSERT(mEGLDevice != nullptr);
ASSERT(mDisplay->getDevice() != nullptr);
mCreatedWithDeviceEXT = true;
// Also set EGL_PLATFORM_ANGLE_ANGLE variables, in case they're used elsewhere in ANGLE
......@@ -832,9 +830,12 @@ egl::Error Renderer11::initializeD3DDevice()
}
else
{
DeviceD3D *deviceD3D = GetImplAs<DeviceD3D>(mDisplay->getDevice());
ASSERT(deviceD3D != nullptr);
// We should use the inputted D3D11 device instead
void *device = nullptr;
ANGLE_TRY(mEGLDevice->getDevice(&device));
ANGLE_TRY(deviceD3D->getDevice(&device));
ID3D11Device *d3dDevice = reinterpret_cast<ID3D11Device *>(device);
if (FAILED(d3dDevice->GetDeviceRemovedReason()))
......@@ -2096,13 +2097,6 @@ void Renderer11::release()
releaseDeviceResources();
if (!mCreatedWithDeviceEXT)
{
// Only delete the device if the Renderer11 owns it
// Otherwise we should keep it around in case we try to reinitialize the renderer later
SafeDelete(mEGLDevice);
}
SafeRelease(mDxgiFactory);
SafeRelease(mDxgiAdapter);
......@@ -3808,18 +3802,9 @@ angle::WorkaroundsD3D Renderer11::generateWorkarounds() const
return d3d11::GenerateWorkarounds(mRenderer11DeviceCaps, mAdapterDescription);
}
egl::Error Renderer11::getEGLDevice(DeviceImpl **device)
DeviceImpl *Renderer11::createEGLDevice()
{
if (mEGLDevice == nullptr)
{
ASSERT(mDevice != nullptr);
std::unique_ptr<DeviceD3D> newDevice(new DeviceD3D(EGL_D3D11_DEVICE_ANGLE, mDevice));
ANGLE_TRY(newDevice->initialize());
mEGLDevice = newDevice.release();
}
*device = static_cast<DeviceImpl *>(mEGLDevice);
return egl::NoError();
return new DeviceD3D(EGL_D3D11_DEVICE_ANGLE, mDevice);
}
ContextImpl *Renderer11::createContext(const gl::ContextState &state)
......
......@@ -377,7 +377,7 @@ class Renderer11 : public RendererD3D
void onBufferCreate(const Buffer11 *created);
void onBufferDelete(const Buffer11 *deleted);
egl::Error getEGLDevice(DeviceImpl **device) override;
DeviceImpl *createEGLDevice() override;
gl::Error drawArrays(const gl::Context *context,
GLenum mode,
......@@ -525,7 +525,6 @@ class Renderer11 : public RendererD3D
D3D_DRIVER_TYPE mRequestedDriverType;
bool mCreateDebugDevice;
bool mCreatedWithDeviceEXT;
DeviceD3D *mEGLDevice;
HLSLCompiler mCompiler;
......
......@@ -132,8 +132,6 @@ Renderer9::Renderer9(egl::Display *display) : RendererD3D(display), mStateManage
mAppliedProgramSerial = 0;
gl::InitializeDebugAnnotations(&mAnnotator);
mEGLDevice = nullptr;
}
Renderer9::~Renderer9()
......@@ -160,7 +158,6 @@ void Renderer9::release()
releaseDeviceResources();
SafeDelete(mEGLDevice);
SafeRelease(mDevice);
SafeRelease(mDeviceEx);
SafeRelease(mD3d9);
......@@ -3084,18 +3081,9 @@ angle::WorkaroundsD3D Renderer9::generateWorkarounds() const
return d3d9::GenerateWorkarounds();
}
egl::Error Renderer9::getEGLDevice(DeviceImpl **device)
DeviceImpl *Renderer9::createEGLDevice()
{
if (mEGLDevice == nullptr)
{
ASSERT(mDevice != nullptr);
std::unique_ptr<DeviceD3D> newDevice(new DeviceD3D(EGL_D3D9_DEVICE_ANGLE, mDevice));
ANGLE_TRY(newDevice->initialize());
mEGLDevice = newDevice.release();
}
*device = static_cast<DeviceImpl *>(mEGLDevice);
return egl::NoError();
return new DeviceD3D(EGL_D3D9_DEVICE_ANGLE, mDevice);
}
Renderer9::CurSamplerState::CurSamplerState()
......
......@@ -356,7 +356,7 @@ class Renderer9 : public RendererD3D
D3DDEVTYPE getD3D9DeviceType() const { return mDeviceType; }
egl::Error getEGLDevice(DeviceImpl **device) override;
DeviceImpl *createEGLDevice() override;
StateManager9 *getStateManager() { return &mStateManager; }
......@@ -531,7 +531,6 @@ class Renderer9 : public RendererD3D
} mNullColorbufferCache[NUM_NULL_COLORBUFFER_CACHE_ENTRIES];
UINT mMaxNullColorbufferLRU;
DeviceD3D *mEGLDevice;
std::vector<TranslatedAttribute> mTranslatedAttribCache;
DebugAnnotator9 mAnnotator;
......
......@@ -50,7 +50,7 @@ class DisplayCGL : public DisplayGL
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const override;
egl::Error getDevice(DeviceImpl **device) override;
DeviceImpl *createDevice() override;
std::string getVendorString() const override;
......
......@@ -145,10 +145,10 @@ SurfaceImpl *DisplayCGL::createPixmapSurface(const egl::SurfaceState &state,
return nullptr;
}
egl::Error DisplayCGL::getDevice(DeviceImpl **device)
DeviceImpl *DisplayCGL::createDevice()
{
UNIMPLEMENTED();
return egl::EglBadDisplay();
return nullptr;
}
egl::ConfigSet DisplayCGL::generateConfigs()
......
......@@ -377,10 +377,10 @@ bool DisplayAndroid::isValidNativeWindow(EGLNativeWindowType window) const
return ANativeWindow_getFormat(window) >= 0;
}
egl::Error DisplayAndroid::getDevice(DeviceImpl **device)
DeviceImpl *DisplayAndroid::createDevice()
{
UNIMPLEMENTED();
return egl::NoError();
return nullptr;
}
egl::Error DisplayAndroid::waitClient(const gl::Context *context) const
......
......@@ -51,7 +51,7 @@ class DisplayAndroid : public DisplayEGL
bool isValidNativeWindow(EGLNativeWindowType window) const override;
egl::Error getDevice(DeviceImpl **device) override;
DeviceImpl *createDevice() override;
egl::Error waitClient(const gl::Context *context) const override;
egl::Error waitNative(const gl::Context *context, EGLint engine) const override;
......
......@@ -895,10 +895,10 @@ SurfaceImpl *DisplayOzone::createPixmapSurface(const egl::SurfaceState &state,
return nullptr;
}
egl::Error DisplayOzone::getDevice(DeviceImpl **device)
DeviceImpl *DisplayOzone::createDevice()
{
UNIMPLEMENTED();
return egl::EglBadDisplay();
return nullptr;
}
egl::ConfigSet DisplayOzone::generateConfigs()
......
......@@ -133,7 +133,7 @@ class DisplayOzone final : public DisplayEGL
bool isValidNativeWindow(EGLNativeWindowType window) const override;
egl::Error getDevice(DeviceImpl **device) override;
DeviceImpl *createDevice() override;
egl::Error waitClient(const gl::Context *context) const override;
egl::Error waitNative(const gl::Context *context, EGLint engine) const override;
......
......@@ -393,10 +393,10 @@ SurfaceImpl *DisplayGLX::createPixmapSurface(const egl::SurfaceState &state,
return nullptr;
}
egl::Error DisplayGLX::getDevice(DeviceImpl **device)
DeviceImpl *DisplayGLX::createDevice()
{
UNIMPLEMENTED();
return egl::EglBadDisplay();
return nullptr;
}
egl::Error DisplayGLX::initializeContext(glx::FBConfig config,
......
......@@ -68,7 +68,7 @@ class DisplayGLX : public DisplayGL
bool isValidNativeWindow(EGLNativeWindowType window) const override;
egl::Error getDevice(DeviceImpl **device) override;
DeviceImpl *createDevice() override;
std::string getVendorString() const override;
......
......@@ -432,10 +432,10 @@ SurfaceImpl *DisplayWGL::createPixmapSurface(const egl::SurfaceState &state,
return nullptr;
}
egl::Error DisplayWGL::getDevice(DeviceImpl **device)
DeviceImpl *DisplayWGL::createDevice()
{
UNIMPLEMENTED();
return egl::EglBadDisplay();
UNREACHABLE();
return nullptr;
}
egl::ConfigSet DisplayWGL::generateConfigs()
......
......@@ -52,7 +52,7 @@ class DisplayWGL : public DisplayGL
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const override;
egl::Error getDevice(DeviceImpl **device) override;
DeviceImpl *createDevice() override;
std::string getVendorString() const override;
......
......@@ -19,7 +19,7 @@
namespace rx
{
DisplayNULL::DisplayNULL(const egl::DisplayState &state) : DisplayImpl(state), mDevice(nullptr)
DisplayNULL::DisplayNULL(const egl::DisplayState &state) : DisplayImpl(state)
{
}
......@@ -29,8 +29,6 @@ DisplayNULL::~DisplayNULL()
egl::Error DisplayNULL::initialize(egl::Display *display)
{
mDevice = new DeviceNULL();
constexpr size_t kMaxTotalAllocationSize = 1 << 28; // 256MB
mAllocationTracker.reset(new AllocationTrackerNULL(kMaxTotalAllocationSize));
......@@ -40,7 +38,6 @@ egl::Error DisplayNULL::initialize(egl::Display *display)
void DisplayNULL::terminate()
{
mAllocationTracker.reset();
SafeDelete(mDevice);
}
egl::Error DisplayNULL::makeCurrent(egl::Surface *drawSurface,
......@@ -113,10 +110,9 @@ std::string DisplayNULL::getVendorString() const
return "NULL";
}
egl::Error DisplayNULL::getDevice(DeviceImpl **device)
DeviceImpl *DisplayNULL::createDevice()
{
*device = mDevice;
return egl::NoError();
return new DeviceNULL();
}
egl::Error DisplayNULL::waitClient(const gl::Context *context) const
......
......@@ -39,7 +39,7 @@ class DisplayNULL : public DisplayImpl
std::string getVendorString() const override;
egl::Error getDevice(DeviceImpl **device) override;
DeviceImpl *createDevice() override;
egl::Error waitClient(const gl::Context *context) const override;
egl::Error waitNative(const gl::Context *context, EGLint engine) const override;
......@@ -71,8 +71,6 @@ class DisplayNULL : public DisplayImpl
void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
void generateCaps(egl::Caps *outCaps) const override;
DeviceImpl *mDevice;
std::unique_ptr<AllocationTrackerNULL> mAllocationTracker;
};
......
......@@ -115,9 +115,10 @@ std::string DisplayVk::getVendorString() const
return vendorString;
}
egl::Error DisplayVk::getDevice(DeviceImpl **device)
DeviceImpl *DisplayVk::createDevice()
{
return egl::NoError();
UNIMPLEMENTED();
return nullptr;
}
egl::Error DisplayVk::waitClient(const gl::Context *context) const
......
......@@ -36,7 +36,7 @@ class DisplayVk : public DisplayImpl
std::string getVendorString() const override;
egl::Error getDevice(DeviceImpl **device) override;
DeviceImpl *createDevice() override;
egl::Error waitClient(const gl::Context *context) const override;
egl::Error waitNative(const gl::Context *context, EGLint engine) const override;
......
......@@ -351,7 +351,7 @@ ANGLE_EXPORT EGLDeviceEXT EGLAPIENTRY CreateDeviceANGLE(EGLint device_type,
}
Device *device = nullptr;
error = Device::CreateDevice(native_device, device_type, &device);
error = Device::CreateDevice(device_type, native_device, &device);
if (error.isError())
{
ASSERT(device == nullptr);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment