Merge "Fix sensor uuid, retrofit recent event logger" into nyc-dev
diff --git a/cmds/servicemanager/servicemanager.rc b/cmds/servicemanager/servicemanager.rc
index 1ba339d..aee7bd8 100644
--- a/cmds/servicemanager/servicemanager.rc
+++ b/cmds/servicemanager/servicemanager.rc
@@ -11,4 +11,5 @@
onrestart restart inputflinger
onrestart restart drm
onrestart restart cameraserver
+ writepid /dev/cpuset/system-background/tasks
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 620cf89..0b7ce17 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -844,30 +844,31 @@
mCore->mQueue.push_back(item);
frameAvailableListener = mCore->mConsumerListener;
} else {
- // When the queue is not empty, we need to look at the front buffer
- // state to see if we need to replace it
- BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
- if (front->mIsDroppable) {
+ // When the queue is not empty, we need to look at the last buffer
+ // in the queue to see if we need to replace it
+ const BufferItem& last = mCore->mQueue.itemAt(
+ mCore->mQueue.size() - 1);
+ if (last.mIsDroppable) {
- if (!front->mIsStale) {
- mSlots[front->mSlot].mBufferState.freeQueued();
+ if (!last.mIsStale) {
+ mSlots[last.mSlot].mBufferState.freeQueued();
// After leaving shared buffer mode, the shared buffer will
// still be around. Mark it as no longer shared if this
// operation causes it to be free.
if (!mCore->mSharedBufferMode &&
- mSlots[front->mSlot].mBufferState.isFree()) {
- mSlots[front->mSlot].mBufferState.mShared = false;
+ mSlots[last.mSlot].mBufferState.isFree()) {
+ mSlots[last.mSlot].mBufferState.mShared = false;
}
// Don't put the shared buffer on the free list.
- if (!mSlots[front->mSlot].mBufferState.isShared()) {
- mCore->mActiveBuffers.erase(front->mSlot);
- mCore->mFreeBuffers.push_back(front->mSlot);
+ if (!mSlots[last.mSlot].mBufferState.isShared()) {
+ mCore->mActiveBuffers.erase(last.mSlot);
+ mCore->mFreeBuffers.push_back(last.mSlot);
}
}
// Overwrite the droppable buffer with the incoming one
- *front = item;
+ mCore->mQueue.editItemAt(mCore->mQueue.size() - 1) = item;
frameReplacedListener = mCore->mConsumerListener;
} else {
mCore->mQueue.push_back(item);
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index df639cd..217c821 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -605,7 +605,6 @@
EGLBoolean result = s->cnx->egl.eglDestroySurface(dp->disp.dpy, s->surface);
if (result == EGL_TRUE) {
_s.terminate();
- dp->removeSurface(surface);
}
return result;
}
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index c368bad..e335a6c 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -90,31 +90,6 @@
return false;
}
-void egl_display_t::addContext(egl_context_t* context) {
- Mutex::Autolock _l(lock);
- contexts.add(context);
-}
-
-void egl_display_t::removeContext(egl_context_t* context) {
- Mutex::Autolock _l(lock);
- contexts.remove(context);
-}
-
-void egl_display_t::removeSurface(EGLSurface surface) const {
- Mutex::Autolock _l(lock);
- for (size_t i = 0; i < contexts.size(); i++) {
- egl_context_t* context = contexts[i];
- if (context->read == surface) {
- SurfaceRef _r(get_surface(context->read));
- _r.release();
- }
- if (context->draw == surface) {
- SurfaceRef _d(get_surface(context->draw));
- _d.release();
- }
- }
-}
-
EGLDisplay egl_display_t::getFromNativeDisplay(EGLNativeDisplayType disp) {
if (uintptr_t(disp) >= NUM_DISPLAYS)
return NULL;
diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h
index 0ede705..2d86295 100644
--- a/opengl/libs/EGL/egl_display.h
+++ b/opengl/libs/EGL/egl_display.h
@@ -68,13 +68,6 @@
// add reference to this object. returns true if this is a valid object.
bool getObject(egl_object_t* object) const;
- // add context to this display's list
- void addContext(egl_context_t* context);
- // remove context from this display's list
- void removeContext(egl_context_t* context);
- // search for surface on all contexts and remove the references
- void removeSurface(EGLSurface surface) const;
-
// These notifications allow the display to keep track of how many window
// surfaces exist, which it uses to decide whether to hibernate the
// underlying EGL implementation. They can be called by any thread without
@@ -142,7 +135,6 @@
mutable Mutex lock, refLock;
mutable Condition refCond;
SortedVector<egl_object_t*> objects;
- SortedVector<egl_context_t*> contexts;
String8 mVendorString;
String8 mVersionString;
String8 mClientApiString;
diff --git a/opengl/libs/EGL/egl_object.cpp b/opengl/libs/EGL/egl_object.cpp
index 8859387..918faa8 100644
--- a/opengl/libs/EGL/egl_object.cpp
+++ b/opengl/libs/EGL/egl_object.cpp
@@ -91,12 +91,6 @@
egl_connection_t const* cnx, int version) :
egl_object_t(get_display_nowake(dpy)), dpy(dpy), context(context),
config(config), read(0), draw(0), cnx(cnx), version(version) {
- get_display_nowake(dpy)->addContext(this);
-}
-
-void egl_context_t::terminate() {
- display->removeContext(this);
- egl_object_t::terminate();
}
void egl_context_t::onLooseCurrent() {
diff --git a/opengl/libs/EGL/egl_object.h b/opengl/libs/EGL/egl_object.h
index 8268900..17a8304 100644
--- a/opengl/libs/EGL/egl_object.h
+++ b/opengl/libs/EGL/egl_object.h
@@ -40,12 +40,11 @@
class egl_display_t;
class egl_object_t {
+ egl_display_t *display;
mutable volatile int32_t count;
protected:
virtual ~egl_object_t();
- virtual void terminate();
- egl_display_t *display;
public:
egl_object_t(egl_display_t* display);
@@ -56,6 +55,7 @@
inline egl_display_t* getDisplay() const { return display; }
private:
+ void terminate();
static bool get(egl_display_t const* display, egl_object_t* object);
public:
@@ -143,7 +143,6 @@
class egl_context_t: public egl_object_t {
protected:
~egl_context_t() {}
- void terminate() override;
public:
typedef egl_object_t::LocalRef<egl_context_t, EGLContext> Ref;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 6ccd4ff..c640f58 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -251,7 +251,7 @@
ALOGE("Can't replace a frame on an empty queue");
return;
}
- mQueueItems.editItemAt(0) = item;
+ mQueueItems.editItemAt(mQueueItems.size() - 1) = item;
// Wake up any pending callbacks
mLastFrameNumberReceived = item.mFrameNumber;
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 17ccc72..b02f5b4 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -480,17 +480,20 @@
if (hook->type == ProcHook::GLOBAL)
return hook->proc;
+ // v0 layers expect
+ //
+ // vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice");
+ //
+ // to work.
+ if (strcmp(pName, "vkCreateDevice") == 0)
+ return hook->proc;
+
ALOGE(
"Invalid use of vkGetInstanceProcAddr to query %s without an "
"instance",
pName);
- // Some naughty layers expect
- //
- // vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice");
- //
- // to work.
- return (strcmp(pName, "vkCreateDevice") == 0) ? hook->proc : nullptr;
+ return nullptr;
}
PFN_vkVoidFunction proc;
diff --git a/vulkan/libvulkan/layers_extensions.cpp b/vulkan/libvulkan/layers_extensions.cpp
index 6b53a9a..4cf1c2a 100644
--- a/vulkan/libvulkan/layers_extensions.cpp
+++ b/vulkan/libvulkan/layers_extensions.cpp
@@ -43,75 +43,118 @@
// probably want to intern strings, etc., and will need some custom/manual data
// structures.
-// TODO(jessehall): Currently we have separate lists for instance and device
-// layers. Most layers are both; we should use one entry for each layer name,
-// with a mask saying what kind(s) it is.
-
namespace vulkan {
namespace api {
struct Layer {
VkLayerProperties properties;
size_t library_idx;
- std::vector<VkExtensionProperties> extensions;
+
+ bool is_global;
+
+ std::vector<VkExtensionProperties> instance_extensions;
+ std::vector<VkExtensionProperties> device_extensions;
};
namespace {
-std::mutex g_library_mutex;
-struct LayerLibrary {
- std::string path;
- void* dlhandle;
- size_t refcount;
-};
-std::vector<LayerLibrary> g_layer_libraries;
-std::vector<Layer> g_instance_layers;
-std::vector<Layer> g_device_layers;
+class LayerLibrary {
+ public:
+ LayerLibrary(const std::string& path)
+ : path_(path), dlhandle_(nullptr), refcount_(0) {}
-void AddLayerLibrary(const std::string& path) {
- ALOGV("examining layer library '%s'", path.c_str());
-
- void* dlhandle = dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL);
- if (!dlhandle) {
- ALOGW("failed to load layer library '%s': %s", path.c_str(), dlerror());
- return;
+ LayerLibrary(LayerLibrary&& other)
+ : path_(std::move(other.path_)),
+ dlhandle_(other.dlhandle_),
+ refcount_(other.refcount_) {
+ other.dlhandle_ = nullptr;
+ other.refcount_ = 0;
}
+ LayerLibrary(const LayerLibrary&) = delete;
+ LayerLibrary& operator=(const LayerLibrary&) = delete;
+
+ // these are thread-safe
+ bool Open();
+ void Close();
+
+ bool EnumerateLayers(size_t library_idx,
+ std::vector<Layer>& instance_layers) const;
+
+ void* GetGPA(const Layer& layer,
+ const char* gpa_name,
+ size_t gpa_name_len) const;
+
+ private:
+ const std::string path_;
+
+ std::mutex mutex_;
+ void* dlhandle_;
+ size_t refcount_;
+};
+
+bool LayerLibrary::Open() {
+ std::lock_guard<std::mutex> lock(mutex_);
+
+ if (refcount_++ == 0) {
+ dlhandle_ = dlopen(path_.c_str(), RTLD_NOW | RTLD_LOCAL);
+ ALOGV("Opening library %s", path_.c_str());
+ if (!dlhandle_) {
+ ALOGE("failed to load layer library '%s': %s", path_.c_str(),
+ dlerror());
+ refcount_ = 0;
+ return false;
+ }
+ }
+ ALOGV("Refcount on activate is %zu", refcount_);
+ return true;
+}
+
+void LayerLibrary::Close() {
+ std::lock_guard<std::mutex> lock(mutex_);
+
+ if (--refcount_ == 0) {
+ ALOGV("Closing library %s", path_.c_str());
+ dlclose(dlhandle_);
+ dlhandle_ = nullptr;
+ }
+ ALOGV("Refcount on destruction is %zu", refcount_);
+}
+
+bool LayerLibrary::EnumerateLayers(size_t library_idx,
+ std::vector<Layer>& instance_layers) const {
PFN_vkEnumerateInstanceLayerProperties enumerate_instance_layers =
reinterpret_cast<PFN_vkEnumerateInstanceLayerProperties>(
- dlsym(dlhandle, "vkEnumerateInstanceLayerProperties"));
+ dlsym(dlhandle_, "vkEnumerateInstanceLayerProperties"));
PFN_vkEnumerateInstanceExtensionProperties enumerate_instance_extensions =
reinterpret_cast<PFN_vkEnumerateInstanceExtensionProperties>(
- dlsym(dlhandle, "vkEnumerateInstanceExtensionProperties"));
- PFN_vkEnumerateDeviceLayerProperties enumerate_device_layers =
- reinterpret_cast<PFN_vkEnumerateDeviceLayerProperties>(
- dlsym(dlhandle, "vkEnumerateDeviceLayerProperties"));
- PFN_vkEnumerateDeviceExtensionProperties enumerate_device_extensions =
- reinterpret_cast<PFN_vkEnumerateDeviceExtensionProperties>(
- dlsym(dlhandle, "vkEnumerateDeviceExtensionProperties"));
- if (!((enumerate_instance_layers && enumerate_instance_extensions) ||
- (enumerate_device_layers && enumerate_device_extensions))) {
- ALOGV(
- "layer library '%s' has neither instance nor device enumeraion "
- "functions",
- path.c_str());
- dlclose(dlhandle);
- return;
+ dlsym(dlhandle_, "vkEnumerateInstanceExtensionProperties"));
+ if (!enumerate_instance_layers || !enumerate_instance_extensions) {
+ ALOGV("layer library '%s' misses some instance enumeraion functions",
+ path_.c_str());
+ return false;
}
- VkResult result;
+ // device functions are optional
+ PFN_vkEnumerateDeviceLayerProperties enumerate_device_layers =
+ reinterpret_cast<PFN_vkEnumerateDeviceLayerProperties>(
+ dlsym(dlhandle_, "vkEnumerateDeviceLayerProperties"));
+ PFN_vkEnumerateDeviceExtensionProperties enumerate_device_extensions =
+ reinterpret_cast<PFN_vkEnumerateDeviceExtensionProperties>(
+ dlsym(dlhandle_, "vkEnumerateDeviceExtensionProperties"));
+
+ // get layer counts
uint32_t num_instance_layers = 0;
uint32_t num_device_layers = 0;
- if (enumerate_instance_layers) {
- result = enumerate_instance_layers(&num_instance_layers, nullptr);
+ VkResult result = enumerate_instance_layers(&num_instance_layers, nullptr);
+ if (result != VK_SUCCESS || !num_instance_layers) {
if (result != VK_SUCCESS) {
ALOGW(
"vkEnumerateInstanceLayerProperties failed for library '%s': "
"%d",
- path.c_str(), result);
- dlclose(dlhandle);
- return;
+ path_.c_str(), result);
}
+ return false;
}
if (enumerate_device_layers) {
result = enumerate_device_layers(VK_NULL_HANDLE, &num_device_layers,
@@ -119,23 +162,19 @@
if (result != VK_SUCCESS) {
ALOGW(
"vkEnumerateDeviceLayerProperties failed for library '%s': %d",
- path.c_str(), result);
- dlclose(dlhandle);
- return;
+ path_.c_str(), result);
+ return false;
}
}
+
+ // get layer properties
VkLayerProperties* properties = static_cast<VkLayerProperties*>(alloca(
(num_instance_layers + num_device_layers) * sizeof(VkLayerProperties)));
- if (num_instance_layers > 0) {
- result = enumerate_instance_layers(&num_instance_layers, properties);
- if (result != VK_SUCCESS) {
- ALOGW(
- "vkEnumerateInstanceLayerProperties failed for library '%s': "
- "%d",
- path.c_str(), result);
- dlclose(dlhandle);
- return;
- }
+ result = enumerate_instance_layers(&num_instance_layers, properties);
+ if (result != VK_SUCCESS) {
+ ALOGW("vkEnumerateInstanceLayerProperties failed for library '%s': %d",
+ path_.c_str(), result);
+ return false;
}
if (num_device_layers > 0) {
result = enumerate_device_layers(VK_NULL_HANDLE, &num_device_layers,
@@ -143,102 +182,121 @@
if (result != VK_SUCCESS) {
ALOGW(
"vkEnumerateDeviceLayerProperties failed for library '%s': %d",
- path.c_str(), result);
- dlclose(dlhandle);
- return;
+ path_.c_str(), result);
+ return false;
}
}
- size_t library_idx = g_layer_libraries.size();
- size_t prev_num_instance_layers = g_instance_layers.size();
- size_t prev_num_device_layers = g_device_layers.size();
- g_instance_layers.reserve(prev_num_instance_layers + num_instance_layers);
- g_device_layers.reserve(prev_num_device_layers + num_device_layers);
+ // append layers to instance_layers
+ size_t prev_num_instance_layers = instance_layers.size();
+ instance_layers.reserve(prev_num_instance_layers + num_instance_layers);
for (size_t i = 0; i < num_instance_layers; i++) {
const VkLayerProperties& props = properties[i];
Layer layer;
layer.properties = props;
layer.library_idx = library_idx;
+ layer.is_global = false;
- if (enumerate_instance_extensions) {
- uint32_t count = 0;
- result =
- enumerate_instance_extensions(props.layerName, &count, nullptr);
- if (result != VK_SUCCESS) {
- ALOGW(
- "vkEnumerateInstanceExtensionProperties(%s) failed for "
- "library "
- "'%s': %d",
- props.layerName, path.c_str(), result);
- g_instance_layers.resize(prev_num_instance_layers);
- dlclose(dlhandle);
- return;
- }
- layer.extensions.resize(count);
- result = enumerate_instance_extensions(props.layerName, &count,
- layer.extensions.data());
- if (result != VK_SUCCESS) {
- ALOGW(
- "vkEnumerateInstanceExtensionProperties(%s) failed for "
- "library "
- "'%s': %d",
- props.layerName, path.c_str(), result);
- g_instance_layers.resize(prev_num_instance_layers);
- dlclose(dlhandle);
- return;
+ uint32_t count = 0;
+ result =
+ enumerate_instance_extensions(props.layerName, &count, nullptr);
+ if (result != VK_SUCCESS) {
+ ALOGW(
+ "vkEnumerateInstanceExtensionProperties(%s) failed for library "
+ "'%s': %d",
+ props.layerName, path_.c_str(), result);
+ instance_layers.resize(prev_num_instance_layers);
+ return false;
+ }
+ layer.instance_extensions.resize(count);
+ result = enumerate_instance_extensions(
+ props.layerName, &count, layer.instance_extensions.data());
+ if (result != VK_SUCCESS) {
+ ALOGW(
+ "vkEnumerateInstanceExtensionProperties(%s) failed for library "
+ "'%s': %d",
+ props.layerName, path_.c_str(), result);
+ instance_layers.resize(prev_num_instance_layers);
+ return false;
+ }
+
+ for (size_t j = 0; j < num_device_layers; j++) {
+ const auto& dev_props = properties[num_instance_layers + j];
+ if (memcmp(&props, &dev_props, sizeof(props)) == 0) {
+ layer.is_global = true;
+ break;
}
}
- g_instance_layers.push_back(layer);
- ALOGV(" added instance layer '%s'", props.layerName);
- }
- for (size_t i = 0; i < num_device_layers; i++) {
- const VkLayerProperties& props = properties[num_instance_layers + i];
-
- Layer layer;
- layer.properties = props;
- layer.library_idx = library_idx;
-
- if (enumerate_device_extensions) {
- uint32_t count;
+ if (layer.is_global && enumerate_device_extensions) {
result = enumerate_device_extensions(
VK_NULL_HANDLE, props.layerName, &count, nullptr);
if (result != VK_SUCCESS) {
ALOGW(
"vkEnumerateDeviceExtensionProperties(%s) failed for "
- "library "
- "'%s': %d",
- props.layerName, path.c_str(), result);
- g_instance_layers.resize(prev_num_instance_layers);
- g_device_layers.resize(prev_num_device_layers);
- dlclose(dlhandle);
- return;
+ "library '%s': %d",
+ props.layerName, path_.c_str(), result);
+ instance_layers.resize(prev_num_instance_layers);
+ return false;
}
- layer.extensions.resize(count);
- result =
- enumerate_device_extensions(VK_NULL_HANDLE, props.layerName,
- &count, layer.extensions.data());
+ layer.device_extensions.resize(count);
+ result = enumerate_device_extensions(
+ VK_NULL_HANDLE, props.layerName, &count,
+ layer.device_extensions.data());
if (result != VK_SUCCESS) {
ALOGW(
"vkEnumerateDeviceExtensionProperties(%s) failed for "
- "library "
- "'%s': %d",
- props.layerName, path.c_str(), result);
- g_instance_layers.resize(prev_num_instance_layers);
- g_device_layers.resize(prev_num_device_layers);
- dlclose(dlhandle);
- return;
+ "library '%s': %d",
+ props.layerName, path_.c_str(), result);
+ instance_layers.resize(prev_num_instance_layers);
+ return false;
}
}
- g_device_layers.push_back(layer);
- ALOGV(" added device layer '%s'", props.layerName);
+ instance_layers.push_back(layer);
+ ALOGV(" added %s layer '%s'",
+ (layer.is_global) ? "global" : "instance", props.layerName);
}
- dlclose(dlhandle);
+ return true;
+}
- g_layer_libraries.push_back(LayerLibrary{path, nullptr, 0});
+void* LayerLibrary::GetGPA(const Layer& layer,
+ const char* gpa_name,
+ size_t gpa_name_len) const {
+ void* gpa;
+ size_t layer_name_len =
+ std::max(size_t{2}, strlen(layer.properties.layerName));
+ char* name = static_cast<char*>(alloca(layer_name_len + gpa_name_len + 1));
+ strcpy(name, layer.properties.layerName);
+ strcpy(name + layer_name_len, gpa_name);
+ if (!(gpa = dlsym(dlhandle_, name))) {
+ strcpy(name, "vk");
+ strcpy(name + 2, gpa_name);
+ gpa = dlsym(dlhandle_, name);
+ }
+ return gpa;
+}
+
+std::vector<LayerLibrary> g_layer_libraries;
+std::vector<Layer> g_instance_layers;
+
+void AddLayerLibrary(const std::string& path) {
+ ALOGV("examining layer library '%s'", path.c_str());
+
+ LayerLibrary library(path);
+ if (!library.Open())
+ return;
+
+ if (!library.EnumerateLayers(g_layer_libraries.size(), g_instance_layers)) {
+ library.Close();
+ return;
+ }
+
+ library.Close();
+
+ g_layer_libraries.emplace_back(std::move(library));
}
void DiscoverLayersInDirectory(const std::string& dir_path) {
@@ -271,71 +329,25 @@
closedir(directory);
}
+const Layer* FindInstanceLayer(const char* name) {
+ auto layer =
+ std::find_if(g_instance_layers.cbegin(), g_instance_layers.cend(),
+ [=](const Layer& entry) {
+ return strcmp(entry.properties.layerName, name) == 0;
+ });
+ return (layer != g_instance_layers.cend()) ? &*layer : nullptr;
+}
+
+const Layer* FindDeviceLayer(const char* name) {
+ const Layer* layer = FindInstanceLayer(name);
+ return (layer && layer->is_global) ? layer : nullptr;
+}
+
void* GetLayerGetProcAddr(const Layer& layer,
const char* gpa_name,
size_t gpa_name_len) {
const LayerLibrary& library = g_layer_libraries[layer.library_idx];
- void* gpa;
- size_t layer_name_len = std::max(size_t{2}, strlen(layer.properties.layerName));
- char* name = static_cast<char*>(alloca(layer_name_len + gpa_name_len + 1));
- strcpy(name, layer.properties.layerName);
- strcpy(name + layer_name_len, gpa_name);
- if (!(gpa = dlsym(library.dlhandle, name))) {
- strcpy(name, "vk");
- strcpy(name + 2, gpa_name);
- gpa = dlsym(library.dlhandle, name);
- }
- return gpa;
-}
-
-uint32_t EnumerateLayers(const std::vector<Layer>& layers,
- uint32_t count,
- VkLayerProperties* properties) {
- uint32_t n = std::min(count, static_cast<uint32_t>(layers.size()));
- for (uint32_t i = 0; i < n; i++) {
- properties[i] = layers[i].properties;
- }
- return static_cast<uint32_t>(layers.size());
-}
-
-void GetLayerExtensions(const std::vector<Layer>& layers,
- const char* name,
- const VkExtensionProperties** properties,
- uint32_t* count) {
- auto layer =
- std::find_if(layers.cbegin(), layers.cend(), [=](const Layer& entry) {
- return strcmp(entry.properties.layerName, name) == 0;
- });
- if (layer == layers.cend()) {
- *properties = nullptr;
- *count = 0;
- } else {
- *properties = layer->extensions.data();
- *count = static_cast<uint32_t>(layer->extensions.size());
- }
-}
-
-LayerRef GetLayerRef(std::vector<Layer>& layers, const char* name) {
- for (uint32_t id = 0; id < layers.size(); id++) {
- if (strcmp(name, layers[id].properties.layerName) == 0) {
- LayerLibrary& library = g_layer_libraries[layers[id].library_idx];
- std::lock_guard<std::mutex> lock(g_library_mutex);
- if (library.refcount++ == 0) {
- library.dlhandle =
- dlopen(library.path.c_str(), RTLD_NOW | RTLD_LOCAL);
- ALOGV("Opening library %s", library.path.c_str());
- if (!library.dlhandle) {
- ALOGE("failed to load layer library '%s': %s",
- library.path.c_str(), dlerror());
- library.refcount = 0;
- return LayerRef(nullptr);
- }
- }
- ALOGV("Refcount on activate is %zu", library.refcount);
- return LayerRef(&layers[id]);
- }
- }
- return LayerRef(nullptr);
+ return library.GetGPA(layer, gpa_name, gpa_name_len);
}
} // anonymous namespace
@@ -349,45 +361,84 @@
uint32_t EnumerateInstanceLayers(uint32_t count,
VkLayerProperties* properties) {
- return EnumerateLayers(g_instance_layers, count, properties);
+ uint32_t n =
+ std::min(count, static_cast<uint32_t>(g_instance_layers.size()));
+ for (uint32_t i = 0; i < n; i++)
+ properties[i] = g_instance_layers[i].properties;
+
+ return static_cast<uint32_t>(g_instance_layers.size());
}
uint32_t EnumerateDeviceLayers(uint32_t count, VkLayerProperties* properties) {
- return EnumerateLayers(g_device_layers, count, properties);
+ uint32_t n = 0;
+ for (const auto& layer : g_instance_layers) {
+ // ignore non-global layers
+ if (!layer.is_global)
+ continue;
+
+ if (n < count)
+ properties[n] = layer.properties;
+ n++;
+ }
+
+ return n;
}
void GetInstanceLayerExtensions(const char* name,
const VkExtensionProperties** properties,
uint32_t* count) {
- GetLayerExtensions(g_instance_layers, name, properties, count);
+ const Layer* layer = FindInstanceLayer(name);
+ if (layer) {
+ *properties = layer->instance_extensions.data();
+ *count = static_cast<uint32_t>(layer->instance_extensions.size());
+ } else {
+ *properties = nullptr;
+ *count = 0;
+ }
}
void GetDeviceLayerExtensions(const char* name,
const VkExtensionProperties** properties,
uint32_t* count) {
- GetLayerExtensions(g_device_layers, name, properties, count);
+ const Layer* layer = FindDeviceLayer(name);
+ if (layer) {
+ *properties = layer->device_extensions.data();
+ *count = static_cast<uint32_t>(layer->device_extensions.size());
+ } else {
+ *properties = nullptr;
+ *count = 0;
+ }
}
LayerRef GetInstanceLayerRef(const char* name) {
- return GetLayerRef(g_instance_layers, name);
+ const Layer* layer = FindInstanceLayer(name);
+ if (layer) {
+ LayerLibrary& library = g_layer_libraries[layer->library_idx];
+ if (!library.Open())
+ layer = nullptr;
+ }
+
+ return LayerRef(layer, true);
}
LayerRef GetDeviceLayerRef(const char* name) {
- return GetLayerRef(g_device_layers, name);
+ const Layer* layer = FindDeviceLayer(name);
+ if (layer) {
+ LayerLibrary& library = g_layer_libraries[layer->library_idx];
+ if (!library.Open())
+ layer = nullptr;
+ }
+
+ return LayerRef(layer, false);
}
-LayerRef::LayerRef(Layer* layer) : layer_(layer) {}
+LayerRef::LayerRef(const Layer* layer, bool is_instance)
+ : layer_(layer), is_instance_(is_instance) {}
LayerRef::~LayerRef() {
if (layer_) {
LayerLibrary& library = g_layer_libraries[layer_->library_idx];
- std::lock_guard<std::mutex> lock(g_library_mutex);
- if (--library.refcount == 0) {
- ALOGV("Closing library %s", library.path.c_str());
- dlclose(library.dlhandle);
- library.dlhandle = nullptr;
- }
- ALOGV("Refcount on destruction is %zu", library.refcount);
+ library.Close();
}
}
@@ -395,11 +446,12 @@
return layer_->properties.layerName;
}
-uint32_t LayerRef::GetSpecVersion() {
+uint32_t LayerRef::GetSpecVersion() const {
return layer_->properties.specVersion;
}
-LayerRef::LayerRef(LayerRef&& other) : layer_(std::move(other.layer_)) {
+LayerRef::LayerRef(LayerRef&& other)
+ : layer_(other.layer_), is_instance_(other.is_instance_) {
other.layer_ = nullptr;
}
@@ -416,10 +468,12 @@
}
bool LayerRef::SupportsExtension(const char* name) const {
- return std::find_if(layer_->extensions.cbegin(), layer_->extensions.cend(),
+ const auto& extensions = (is_instance_) ? layer_->instance_extensions
+ : layer_->device_extensions;
+ return std::find_if(extensions.cbegin(), extensions.cend(),
[=](const VkExtensionProperties& ext) {
return strcmp(ext.extensionName, name) == 0;
- }) != layer_->extensions.cend();
+ }) != extensions.cend();
}
} // namespace api
diff --git a/vulkan/libvulkan/layers_extensions.h b/vulkan/libvulkan/layers_extensions.h
index 7e7bfd3..e2eb32b 100644
--- a/vulkan/libvulkan/layers_extensions.h
+++ b/vulkan/libvulkan/layers_extensions.h
@@ -25,14 +25,14 @@
struct Layer;
class LayerRef {
public:
- LayerRef(Layer* layer);
+ LayerRef(const Layer* layer, bool is_instance);
LayerRef(LayerRef&& other);
~LayerRef();
LayerRef(const LayerRef&) = delete;
LayerRef& operator=(const LayerRef&) = delete;
const char* GetName() const;
- uint32_t GetSpecVersion();
+ uint32_t GetSpecVersion() const;
// provides bool-like behavior
operator const Layer*() const { return layer_; }
@@ -43,7 +43,8 @@
bool SupportsExtension(const char* name) const;
private:
- Layer* layer_;
+ const Layer* layer_;
+ bool is_instance_;
};
void DiscoverLayers();
diff --git a/vulkan/libvulkan/stubhal.cpp b/vulkan/libvulkan/stubhal.cpp
index 89fcebb..a74d370 100644
--- a/vulkan/libvulkan/stubhal.cpp
+++ b/vulkan/libvulkan/stubhal.cpp
@@ -83,7 +83,7 @@
std::lock_guard<std::mutex> lock(g_instance_mutex);
ssize_t idx =
reinterpret_cast<hwvulkan_dispatch_t*>(instance) - &g_instances[0];
- ALOG_ASSERT(idx >= 0 && idx < g_instance_used.size(),
+ ALOG_ASSERT(idx >= 0 && static_cast<size_t>(idx) < g_instance_used.size(),
"DestroyInstance: invalid instance handle");
g_instance_used[static_cast<size_t>(idx)] = false;
}
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index e990cf4..69e8e84 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -329,6 +329,17 @@
int err;
VkResult result = VK_SUCCESS;
+ ALOGV("vkCreateSwapchainKHR: surface=0x%" PRIx64
+ " minImageCount=%u imageFormat=%u imageColorSpace=%u"
+ " imageExtent=%ux%u imageUsage=%#x preTransform=%u presentMode=%u"
+ " oldSwapchain=0x%" PRIx64,
+ reinterpret_cast<uint64_t>(create_info->surface),
+ create_info->minImageCount, create_info->imageFormat,
+ create_info->imageColorSpace, create_info->imageExtent.width,
+ create_info->imageExtent.height, create_info->imageUsage,
+ create_info->preTransform, create_info->presentMode,
+ reinterpret_cast<uint64_t>(create_info->oldSwapchain));
+
if (!allocator)
allocator = &GetData(device).allocator;
@@ -348,9 +359,32 @@
"swapchain present mode %d not supported",
create_info->presentMode);
+ Surface& surface = *SurfaceFromHandle(create_info->surface);
+
+ // -- Reset the native window --
+ // The native window might have been used previously, and had its properties
+ // changed from defaults. That will affect the answer we get for queries
+ // like MIN_UNDEQUED_BUFFERS. Reset to a known/default state before we
+ // attempt such queries.
+
+ err = native_window_set_buffer_count(surface.window.get(), 0);
+ if (err != 0) {
+ ALOGE("native_window_set_buffer_count(0) failed: %s (%d)",
+ strerror(-err), err);
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ err = surface.window->setSwapInterval(surface.window.get(), 1);
+ if (err != 0) {
+ // TODO(jessehall): Improve error reporting. Can we enumerate possible
+ // errors and translate them to valid Vulkan result codes?
+ ALOGE("native_window->setSwapInterval(1) failed: %s (%d)",
+ strerror(-err), err);
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
// -- Configure the native window --
- Surface& surface = *SurfaceFromHandle(create_info->surface);
const auto& dispatch = GetData(device).driver;
int native_format = HAL_PIXEL_FORMAT_RGBA_8888;
@@ -451,8 +485,8 @@
if (err != 0) {
// TODO(jessehall): Improve error reporting. Can we enumerate possible
// errors and translate them to valid Vulkan result codes?
- ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
- err);
+ ALOGE("native_window_set_buffer_count(%d) failed: %s (%d)", num_images,
+ strerror(-err), err);
return VK_ERROR_INITIALIZATION_FAILED;
}
@@ -477,14 +511,14 @@
return VK_ERROR_INITIALIZATION_FAILED;
}
- err = surface.window->setSwapInterval(
- surface.window.get(),
- create_info->presentMode == VK_PRESENT_MODE_MAILBOX_KHR ? 0 : 1);
+ int swap_interval =
+ create_info->presentMode == VK_PRESENT_MODE_MAILBOX_KHR ? 0 : 1;
+ err = surface.window->setSwapInterval(surface.window.get(), swap_interval);
if (err != 0) {
// TODO(jessehall): Improve error reporting. Can we enumerate possible
// errors and translate them to valid Vulkan result codes?
- ALOGE("native_window->setSwapInterval failed: %s (%d)", strerror(-err),
- err);
+ ALOGE("native_window->setSwapInterval(%d) failed: %s (%d)",
+ swap_interval, strerror(-err), err);
return VK_ERROR_INITIALIZATION_FAILED;
}
diff --git a/vulkan/nulldrv/null_driver.cpp b/vulkan/nulldrv/null_driver.cpp
index 6f57238..f29cb68 100644
--- a/vulkan/nulldrv/null_driver.cpp
+++ b/vulkan/nulldrv/null_driver.cpp
@@ -19,6 +19,7 @@
#include <algorithm>
#include <array>
#include <inttypes.h>
+#include <stdlib.h>
#include <string.h>
#include <log/log.h>
@@ -186,6 +187,58 @@
AllocHandle(type, &device->next_handle[type]));
}
+VKAPI_ATTR void* DefaultAllocate(void*,
+ size_t size,
+ size_t alignment,
+ VkSystemAllocationScope) {
+ void* ptr = nullptr;
+ // Vulkan requires 'alignment' to be a power of two, but posix_memalign
+ // additionally requires that it be at least sizeof(void*).
+ int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
+ return ret == 0 ? ptr : nullptr;
+}
+
+VKAPI_ATTR void* DefaultReallocate(void*,
+ void* ptr,
+ size_t size,
+ size_t alignment,
+ VkSystemAllocationScope) {
+ if (size == 0) {
+ free(ptr);
+ return nullptr;
+ }
+
+ // TODO(jessehall): Right now we never shrink allocations; if the new
+ // request is smaller than the existing chunk, we just continue using it.
+ // The null driver never reallocs, so this doesn't matter. If that changes,
+ // or if this code is copied into some other project, this should probably
+ // have a heuristic to allocate-copy-free when doing so will save "enough"
+ // space.
+ size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
+ if (size <= old_size)
+ return ptr;
+
+ void* new_ptr = nullptr;
+ if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0)
+ return nullptr;
+ if (ptr) {
+ memcpy(new_ptr, ptr, std::min(old_size, size));
+ free(ptr);
+ }
+ return new_ptr;
+}
+
+VKAPI_ATTR void DefaultFree(void*, void* ptr) {
+ free(ptr);
+}
+
+const VkAllocationCallbacks kDefaultAllocCallbacks = {
+ .pUserData = nullptr,
+ .pfnAllocation = DefaultAllocate,
+ .pfnReallocation = DefaultReallocate,
+ .pfnFree = DefaultFree,
+};
+
} // namespace
namespace null_driver {
@@ -239,10 +292,8 @@
VkResult CreateInstance(const VkInstanceCreateInfo* create_info,
const VkAllocationCallbacks* allocator,
VkInstance* out_instance) {
- // Assume the loader provided alloc callbacks even if the app didn't.
- ALOG_ASSERT(
- allocator,
- "Missing alloc callbacks, loader or app should have provided them");
+ if (!allocator)
+ allocator = &kDefaultAllocCallbacks;
VkInstance_T* instance =
static_cast<VkInstance_T*>(allocator->pfnAllocation(
diff --git a/vulkan/tools/vkinfo.cpp b/vulkan/tools/vkinfo.cpp
index e97e5f5..62d8240 100644
--- a/vulkan/tools/vkinfo.cpp
+++ b/vulkan/tools/vkinfo.cpp
@@ -162,8 +162,11 @@
uint32_t num_extensions = 0;
for (const auto& desired_ext : kDesiredExtensions) {
bool available = HasExtension(info.extensions, desired_ext);
- for (size_t i = 0; !available && i < info.layer_extensions.size(); i++)
- available = HasExtension(info.layer_extensions[i], desired_ext);
+ if (options.validate) {
+ for (size_t i = 0; !available && i < info.layer_extensions.size();
+ i++)
+ available = HasExtension(info.layer_extensions[i], desired_ext);
+ }
if (available)
extensions[num_extensions++] = desired_ext;
}
@@ -179,12 +182,11 @@
// clang-format off
const char *kValidationLayers[] = {
"VK_LAYER_GOOGLE_threading",
+ "VK_LAYER_LUNARG_parameter_validation",
"VK_LAYER_LUNARG_device_limits",
- "VK_LAYER_LUNARG_draw_state",
- "VK_LAYER_LUNARG_image",
- "VK_LAYER_LUNARG_mem_tracker",
"VK_LAYER_LUNARG_object_tracker",
- "VK_LAYER_LUNARG_param_checker",
+ "VK_LAYER_LUNARG_image",
+ "VK_LAYER_LUNARG_core_validation",
"VK_LAYER_LUNARG_swapchain",
"VK_LAYER_GOOGLE_unique_objects"
};
@@ -236,8 +238,12 @@
uint32_t num_extensions = 0;
for (const auto& desired_ext : kDesiredExtensions) {
bool available = HasExtension(info->extensions, desired_ext);
- for (size_t i = 0; !available && i < info->layer_extensions.size(); i++)
- available = HasExtension(info->layer_extensions[i], desired_ext);
+ if (options.validate) {
+ for (size_t i = 0; !available && i < info->layer_extensions.size();
+ i++)
+ available =
+ HasExtension(info->layer_extensions[i], desired_ext);
+ }
if (available)
extensions[num_extensions++] = desired_ext;
}
@@ -245,12 +251,11 @@
// clang-format off
const char *kValidationLayers[] = {
"VK_LAYER_GOOGLE_threading",
+ "VK_LAYER_LUNARG_parameter_validation",
"VK_LAYER_LUNARG_device_limits",
- "VK_LAYER_LUNARG_draw_state",
- "VK_LAYER_LUNARG_image",
- "VK_LAYER_LUNARG_mem_tracker",
"VK_LAYER_LUNARG_object_tracker",
- "VK_LAYER_LUNARG_param_checker",
+ "VK_LAYER_LUNARG_image",
+ "VK_LAYER_LUNARG_core_validation",
"VK_LAYER_LUNARG_swapchain",
"VK_LAYER_GOOGLE_unique_objects"
};