Hash :
e1aa9219
Author :
Date :
2018-01-08T17:53:05
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: Geoff Lang <geofflang@chromium.org> Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
//
// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Device.cpp: Implements the egl::Device class, representing the abstract
// device. Implements EGLDevice.
#include "libANGLE/Device.h"
#include <iterator>
#include <platform/Platform.h>
#include <EGL/eglext.h>
#include "common/debug.h"
#include "common/platform.h"
#include "libANGLE/renderer/DeviceImpl.h"
#if defined(ANGLE_ENABLE_D3D11)
#include "libANGLE/renderer/d3d/DeviceD3D.h"
#endif
namespace egl
{
template <typename T>
static std::string GenerateExtensionsString(const T &extensions)
{
std::vector<std::string> extensionsVector = extensions.getStrings();
std::ostringstream stream;
std::copy(extensionsVector.begin(), extensionsVector.end(), std::ostream_iterator<std::string>(stream, " "));
return stream.str();
}
typedef std::set<egl::Device *> DeviceSet;
static DeviceSet *GetDeviceSet()
{
static DeviceSet devices;
return &devices;
}
// Static factory methods
egl::Error Device::CreateDevice(EGLint deviceType, void *nativeDevice, Device **outDevice)
{
*outDevice = nullptr;
std::unique_ptr<rx::DeviceImpl> newDeviceImpl;
#if defined(ANGLE_ENABLE_D3D11)
if (deviceType == EGL_D3D11_DEVICE_ANGLE)
{
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();
}
ANGLE_TRY(newDeviceImpl->initialize());
*outDevice = new Device(nullptr, newDeviceImpl.release());
return NoError();
}
bool Device::IsValidDevice(Device *device)
{
const DeviceSet *deviceSet = GetDeviceSet();
return deviceSet->find(device) != deviceSet->end();
}
Device::Device(Display *owningDisplay, rx::DeviceImpl *impl)
: mOwningDisplay(owningDisplay), mImplementation(impl)
{
ASSERT(GetDeviceSet()->find(this) == GetDeviceSet()->end());
GetDeviceSet()->insert(this);
initDeviceExtensions();
}
Device::~Device()
{
ASSERT(GetDeviceSet()->find(this) != GetDeviceSet()->end());
GetDeviceSet()->erase(this);
}
Error Device::getDevice(EGLAttrib *value)
{
void *nativeDevice = nullptr;
egl::Error error = getImplementation()->getDevice(&nativeDevice);
*value = reinterpret_cast<EGLAttrib>(nativeDevice);
return error;
}
EGLint Device::getType()
{
return getImplementation()->getType();
}
void Device::initDeviceExtensions()
{
mImplementation->generateExtensions(&mDeviceExtensions);
mDeviceExtensionString = GenerateExtensionsString(mDeviceExtensions);
}
const DeviceExtensions &Device::getExtensions() const
{
return mDeviceExtensions;
}
const std::string &Device::getExtensionString() const
{
return mDeviceExtensionString;
}
}