From b3a1a769b9db4f852c7f3487bbf12819fc8070e4 Mon Sep 17 00:00:00 2001
From: twinaphex <libretro@gmail.com>
Date: Thu, 11 Nov 2021 07:43:49 +0100
Subject: [PATCH 1/3] Move location state and camera state out of retroarch.c

---
 Makefile.common        |   1 +
 camera/camera_driver.c | 146 +++++++++++++++++++++++++
 camera/camera_driver.h |  91 ++++++++++++++++
 location_driver.c      |  87 ++++++++++-----
 location_driver.h      |  10 ++
 menu/menu_setting.c    |   1 +
 retroarch.c            | 234 +++++++++++------------------------------
 retroarch.h            |  38 -------
 runloop.h              |   1 +
 9 files changed, 369 insertions(+), 240 deletions(-)
 create mode 100644 camera/camera_driver.c
 create mode 100644 camera/camera_driver.h

diff --git a/Makefile.common b/Makefile.common
index 491b00bd88..840324f852 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -234,6 +234,7 @@ endif
 
 OBJ += frontend/frontend_driver.o \
        retroarch.o \
+       camera/camera_driver.o \
        record/record_driver.o \
        command.o \
        msg_hash.o \
diff --git a/camera/camera_driver.c b/camera/camera_driver.c
new file mode 100644
index 0000000000..8609ef4621
--- /dev/null
+++ b/camera/camera_driver.c
@@ -0,0 +1,146 @@
+/*  RetroArch - A frontend for libretro.
+ *  Copyright (C) 2010-2014 - Hans-Kristian Arntzen
+ *  Copyright (C) 2011-2021 - Daniel De Matteis
+ *
+ *  RetroArch is free software: you can redistribute it and/or modify it under the terms
+ *  of the GNU General Public License as published by the Free Software Found-
+ *  ation, either version 3 of the License, or (at your option) any later version.
+ *
+ *  RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ *  PURPOSE.  See the GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along with RetroArch.
+ *  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdint.h>
+
+#include <libretro.h>
+
+#include "../configuration.h"
+#include "../driver.h"
+#include "../list_special.h"
+#include "../runloop.h"
+#include "../verbosity.h"
+
+#include "camera_driver.h"
+
+static void *nullcamera_init(const char *device, uint64_t caps,
+      unsigned width, unsigned height) { return (void*)-1; }
+static void nullcamera_free(void *data) { }
+static void nullcamera_stop(void *data) { }
+static bool nullcamera_start(void *data) { return true; }
+static bool nullcamera_poll(void *a,
+      retro_camera_frame_raw_framebuffer_t b,
+      retro_camera_frame_opengl_texture_t c) { return true; }
+
+static camera_driver_t camera_null = {
+   nullcamera_init,
+   nullcamera_free,
+   nullcamera_start,
+   nullcamera_stop,
+   nullcamera_poll,
+   "null",
+};
+
+const camera_driver_t *camera_drivers[] = {
+#ifdef HAVE_V4L2
+   &camera_v4l2,
+#endif
+#ifdef EMSCRIPTEN
+   &camera_rwebcam,
+#endif
+#ifdef ANDROID
+   &camera_android,
+#endif
+   &camera_null,
+   NULL,
+};
+
+static camera_driver_state_t camera_driver_st     = {0};
+
+camera_driver_state_t *camera_state_get_ptr(void)
+{
+   return &camera_driver_st;
+}
+
+/**
+ * config_get_camera_driver_options:
+ *
+ * Get an enumerated list of all camera driver names,
+ * separated by '|'.
+ *
+ * Returns: string listing of all camera driver names,
+ * separated by '|'.
+ **/
+const char *config_get_camera_driver_options(void)
+{
+   return char_list_new_special(STRING_LIST_CAMERA_DRIVERS, NULL);
+}
+
+bool driver_camera_start(void)
+{
+   camera_driver_state_t *camera_st = &camera_driver_st;
+   if (     camera_st
+         && camera_st->data
+         && camera_st->driver
+         && camera_st->driver->start)
+   {
+      settings_t *settings = config_get_ptr();
+      bool camera_allow    = settings->bools.camera_allow;
+      if (camera_allow)
+         return camera_st->driver->start(camera_st->data);
+
+      runloop_msg_queue_push(
+            "Camera is explicitly disabled.\n", 1, 180, false,
+            NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
+   }
+   return true;
+}
+
+void driver_camera_stop(void)
+{
+   camera_driver_state_t *camera_st = &camera_driver_st;
+   if (     camera_st->driver
+         && camera_st->driver->stop
+         && camera_st->data)
+      camera_st->driver->stop(camera_st->data);
+}
+
+bool camera_driver_find_driver(const char *prefix,
+      bool verbosity_enabled)
+{
+   settings_t *settings         = config_get_ptr();
+   camera_driver_state_t 
+      *camera_st                = &camera_driver_st;
+   int i                        = (int)driver_find_index(
+         "camera_driver",
+         settings->arrays.camera_driver);
+
+   if (i >= 0)
+      camera_st->driver = (const camera_driver_t*)camera_drivers[i];
+   else
+   {
+      if (verbosity_enabled)
+      {
+         unsigned d;
+         RARCH_ERR("Couldn't find any %s named \"%s\"\n", prefix,
+               settings->arrays.camera_driver);
+         RARCH_LOG_OUTPUT("Available %ss are:\n", prefix);
+         for (d = 0; camera_drivers[d]; d++)
+         {
+            if (camera_drivers[d])
+            {
+               RARCH_LOG_OUTPUT("\t%s\n", camera_drivers[d]->ident);
+            }
+         }
+
+         RARCH_WARN("Going to default to first %s...\n", prefix);
+      }
+
+      if (!(camera_st->driver = (const camera_driver_t*)camera_drivers[0]))
+         return false;
+   }
+   return true;
+}
diff --git a/camera/camera_driver.h b/camera/camera_driver.h
new file mode 100644
index 0000000000..51ecb35d8f
--- /dev/null
+++ b/camera/camera_driver.h
@@ -0,0 +1,91 @@
+/*  RetroArch - A frontend for libretro.
+ *  Copyright (C) 2010-2014 - Hans-Kristian Arntzen
+ *  Copyright (C) 2011-2021 - Daniel De Matteis
+ *
+ *  RetroArch is free software: you can redistribute it and/or modify it under the terms
+ *  of the GNU General Public License as published by the Free Software Found-
+ *  ation, either version 3 of the License, or (at your option) any later version.
+ *
+ *  RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ *  PURPOSE.  See the GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along with RetroArch.
+ *  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _CAMERA_DRIVER_H
+#define _CAMERA_DRIVER_H
+
+#include <stdint.h>
+
+#include <boolean.h>
+#include <retro_common_api.h>
+
+#ifdef HAVE_CONFIG_H
+#include "../config.h"
+#endif /* HAVE_CONFIG_H */
+
+RETRO_BEGIN_DECLS
+
+typedef struct camera_driver
+{
+   /* FIXME: params for initialization - queries for resolution,
+    * framerate, color format which might or might not be honored. */
+   void *(*init)(const char *device, uint64_t buffer_types,
+         unsigned width, unsigned height);
+
+   void (*free)(void *data);
+
+   bool (*start)(void *data);
+   void (*stop)(void *data);
+
+   /* Polls the camera driver.
+    * Will call the appropriate callback if a new frame is ready.
+    * Returns true if a new frame was handled. */
+   bool (*poll)(void *data,
+         retro_camera_frame_raw_framebuffer_t frame_raw_cb,
+         retro_camera_frame_opengl_texture_t frame_gl_cb);
+
+   const char *ident;
+} camera_driver_t;
+
+typedef struct
+{
+   struct retro_camera_callback cb;    /* uint64_t alignment */
+   const camera_driver_t *driver;
+   void *data;
+   bool active;
+} camera_driver_state_t;
+
+extern const camera_driver_t *camera_drivers[];
+
+
+extern camera_driver_t camera_v4l2;
+extern camera_driver_t camera_android;
+extern camera_driver_t camera_rwebcam;
+extern camera_driver_t camera_avfoundation;
+
+/**
+ * config_get_camera_driver_options:
+ *
+ * Get an enumerated list of all camera driver names,
+ * separated by '|'.
+ *
+ * Returns: string listing of all camera driver names,
+ * separated by '|'.
+ **/
+const char* config_get_camera_driver_options(void);
+
+bool driver_camera_start(void);
+
+void driver_camera_stop(void);
+
+bool camera_driver_find_driver(const char *prefix,
+      bool verbosity_enabled);
+
+camera_driver_state_t *camera_state_get_ptr(void);
+
+RETRO_END_DECLS
+
+#endif
diff --git a/location_driver.c b/location_driver.c
index 9e557dadcc..e4c38948ab 100644
--- a/location_driver.c
+++ b/location_driver.c
@@ -19,11 +19,9 @@
 #include "list_special.h"
 #include "location_driver.h"
 #include "retroarch.h"
+#include "runloop.h"
 #include "verbosity.h"
 
-static const location_driver_t *rarch_location_driver;
-static void *rarch_location_data;
-
 static location_driver_t location_null = {
    NULL,
    NULL,
@@ -42,6 +40,13 @@ const location_driver_t *location_drivers[] = {
    NULL,
 };
 
+static location_driver_state_t location_driver_st     = {0};
+
+location_driver_state_t *location_state_get_ptr(void)
+{
+   return &location_driver_st;
+}
+
 const char *config_get_location_driver_options(void)
 {
    return char_list_new_special(STRING_LIST_LOCATION_DRIVERS, NULL);
@@ -52,12 +57,15 @@ void location_driver_find_driver(
       const char *prefix,
       bool verbosity_enabled)
 {
+   location_driver_state_t 
+      *location_st              = &location_driver_st;
    int i                        = (int)driver_find_index(
          "location_driver",
          settings->arrays.location_driver);
 
    if (i >= 0)
-      rarch_location_driver  = (const location_driver_t*)location_drivers[i];
+      location_st->driver       = (const location_driver_t*)
+         location_drivers[i];
    else
    {
       if (verbosity_enabled)
@@ -72,20 +80,23 @@ void location_driver_find_driver(
          RARCH_WARN("Going to default to first %s...\n", prefix);
       }
 
-      rarch_location_driver = (const location_driver_t*)location_drivers[0];
+      location_st->driver = (const location_driver_t*)location_drivers[0];
    }
 }
 
 bool driver_location_start(void)
 {
-   if (     rarch_location_driver
-         && rarch_location_data
-         && rarch_location_driver->start)
+   location_driver_state_t 
+      *location_st              = &location_driver_st;
+   if (     location_st
+         && location_st->data
+         && location_st->driver
+         && location_st->driver->start)
    {
       settings_t *settings = config_get_ptr();
       bool location_allow  = settings->bools.location_allow;
       if (location_allow)
-         return rarch_location_driver->start(rarch_location_data);
+         return location_st->driver->start(location_st->data);
 
       runloop_msg_queue_push("Location is explicitly disabled.\n",
             1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT,
@@ -96,29 +107,38 @@ bool driver_location_start(void)
 
 void driver_location_stop(void)
 {
-   if (     rarch_location_driver
-         && rarch_location_driver->stop
-         && rarch_location_data)
-      rarch_location_driver->stop(rarch_location_data);
+   location_driver_state_t 
+      *location_st              = &location_driver_st;
+   if (     location_st
+         && location_st->driver
+         && location_st->driver->stop
+         && location_st->data)
+      location_st->driver->stop(location_st->data);
 }
 
 void driver_location_set_interval(unsigned interval_msecs,
       unsigned interval_distance)
 {
-   if (     rarch_location_driver
-         && rarch_location_driver->set_interval
-         && rarch_location_data)
-      rarch_location_driver->set_interval(rarch_location_data,
+   location_driver_state_t 
+      *location_st              = &location_driver_st;
+   if (     location_st
+         && location_st->driver
+         && location_st->driver->set_interval
+         && location_st->data)
+      location_st->driver->set_interval(location_st->data,
             interval_msecs, interval_distance);
 }
 
 bool driver_location_get_position(double *lat, double *lon,
       double *horiz_accuracy, double *vert_accuracy)
 {
-   if (     rarch_location_driver
-         && rarch_location_driver->get_position
-         && rarch_location_data)
-      return rarch_location_driver->get_position(rarch_location_data,
+   location_driver_state_t 
+      *location_st              = &location_driver_st;
+   if (     location_st
+         && location_st->driver
+         && location_st->driver->get_position
+         && location_st->data)
+      return location_st->driver->get_position(location_st->data,
             lat, lon, horiz_accuracy, vert_accuracy);
 
    *lat            = 0.0;
@@ -133,18 +153,20 @@ bool init_location(
       settings_t *settings,
       bool verbosity_enabled)
 {
+   location_driver_state_t 
+      *location_st             = &location_driver_st;
    rarch_system_info_t *system = (rarch_system_info_t*)data;
    /* Resource leaks will follow if location 
       interface is initialized twice. */
-   if (rarch_location_data)
+   if (location_st->data)
       return true;
 
    location_driver_find_driver(settings,
          "location driver", verbosity_enabled);
 
-   rarch_location_data = rarch_location_driver->init();
+   location_st->data = location_st->driver->init();
 
-   if (!rarch_location_data)
+   if (!location_st->data)
    {
       RARCH_ERR("Failed to initialize location driver. Will continue without location.\n");
       return false;
@@ -158,21 +180,28 @@ bool init_location(
 
 void uninit_location(void *data)
 {
+   location_driver_state_t 
+      *location_st             = &location_driver_st;
 	rarch_system_info_t *system = (rarch_system_info_t*)data;
 
-   if (rarch_location_data && rarch_location_driver)
+   if (location_st->data && location_st->driver)
    {
       if (system->location_cb.deinitialized)
          system->location_cb.deinitialized();
 
-      if (rarch_location_driver->free)
-         rarch_location_driver->free(rarch_location_data);
+      if (location_st->driver->free)
+         location_st->driver->free(location_st->data);
    }
 
-   rarch_location_data = NULL;
+   location_st->active = false;
+   location_st->data   = NULL;
 }
 
 void destroy_location(void)
 {
-   rarch_location_driver                         = NULL;
+   location_driver_state_t 
+      *location_st     = &location_driver_st;
+
+   location_st->active = false;
+   location_st->driver = NULL;
 }
diff --git a/location_driver.h b/location_driver.h
index 4ac66c7ecf..248cd3e238 100644
--- a/location_driver.h
+++ b/location_driver.h
@@ -38,6 +38,14 @@ typedef struct location_driver
    const char *ident;
 } location_driver_t;
 
+
+typedef struct
+{
+   const location_driver_t *driver;
+   void *data;
+   bool active;
+} location_driver_state_t;
+
 /**
  * config_get_location_driver_options:
  *
@@ -110,6 +118,8 @@ bool init_location(
       settings_t *settings,
       bool verbosity_enabled);
 
+location_driver_state_t *location_state_get_ptr(void);
+
 extern location_driver_t location_corelocation;
 extern location_driver_t location_android;
 
diff --git a/menu/menu_setting.c b/menu/menu_setting.c
index 606927d85d..dd9a6bb6be 100644
--- a/menu/menu_setting.c
+++ b/menu/menu_setting.c
@@ -62,6 +62,7 @@
 #include "menu_setting.h"
 #include "menu_cbs.h"
 #include "menu_driver.h"
+#include "../camera/camera_driver.h"
 #include "../gfx/gfx_animation.h"
 #ifdef HAVE_GFX_WIDGETS
 #include "../gfx/gfx_widgets.h"
diff --git a/retroarch.c b/retroarch.c
index bce601b6ce..3093155821 100644
--- a/retroarch.c
+++ b/retroarch.c
@@ -123,6 +123,8 @@
 
 #include "runtime_file.h"
 #include "runloop.h"
+#include "camera/camera_driver.h"
+#include "location_driver.h"
 #include "record/record_driver.h"
 
 #ifdef HAVE_CONFIG_H
@@ -468,48 +470,10 @@ static const ui_companion_driver_t *ui_companion_drivers[] = {
    NULL
 };
 
-
-static void *nullcamera_init(const char *device, uint64_t caps,
-      unsigned width, unsigned height) { return (void*)-1; }
-static void nullcamera_free(void *data) { }
-static void nullcamera_stop(void *data) { }
-static bool nullcamera_start(void *data) { return true; }
-static bool nullcamera_poll(void *a,
-      retro_camera_frame_raw_framebuffer_t b,
-      retro_camera_frame_opengl_texture_t c) { return true; }
-
-static camera_driver_t camera_null = {
-   nullcamera_init,
-   nullcamera_free,
-   nullcamera_start,
-   nullcamera_stop,
-   nullcamera_poll,
-   "null",
-};
-
-static const camera_driver_t *camera_drivers[] = {
-#ifdef HAVE_V4L2
-   &camera_v4l2,
-#endif
-#ifdef EMSCRIPTEN
-   &camera_rwebcam,
-#endif
-#ifdef ANDROID
-   &camera_android,
-#endif
-   &camera_null,
-   NULL,
-};
-
 /* MAIN GLOBAL VARIABLES */
 struct rarch_state
 {
    struct global              g_extern;         /* retro_time_t alignment */
-   struct retro_camera_callback camera_cb;    /* uint64_t alignment */
-
-   const camera_driver_t *camera_driver;
-   void *camera_data;
-
    const ui_companion_driver_t *ui_companion;
    void *ui_companion_data;
 
@@ -567,11 +531,8 @@ struct rarch_state
 #ifdef HAVE_CONFIGFILE
    bool rarch_block_config_read;
 #endif
-   bool location_driver_active;
    bool bluetooth_driver_active;
    bool wifi_driver_active;
-   bool camera_driver_active;
-
    bool main_ui_companion_is_on_foreground;
 };
 
@@ -619,9 +580,6 @@ static void ui_companion_driver_init_first(struct rarch_state *p_rarch);
 static bool core_load(unsigned poll_type_behavior);
 static bool core_unload_game(void);
 
-static void driver_camera_stop(void);
-static bool driver_camera_start(void);
-
 static const void *find_driver_nonempty(
       const char *label, int i,
       char *s, size_t len);
@@ -8491,17 +8449,14 @@ bool runloop_environment_cb(unsigned cmd, void *data)
       {
          struct retro_camera_callback *cb =
             (struct retro_camera_callback*)data;
+         camera_driver_state_t *camera_st = camera_state_get_ptr();
 
          RARCH_LOG("[Environ]: GET_CAMERA_INTERFACE.\n");
          cb->start                        = driver_camera_start;
          cb->stop                         = driver_camera_stop;
 
-         p_rarch->camera_cb               = *cb;
-
-         if (cb->caps != 0)
-            p_rarch->camera_driver_active = true;
-         else
-            p_rarch->camera_driver_active = false;
+         camera_st->cb                    = *cb;
+         camera_st->active                = (cb->caps != 0);
          break;
       }
 
@@ -8509,6 +8464,8 @@ bool runloop_environment_cb(unsigned cmd, void *data)
       {
          struct retro_location_callback *cb =
             (struct retro_location_callback*)data;
+         location_driver_state_t 
+            *location_st                    = location_state_get_ptr();
 
          RARCH_LOG("[Environ]: GET_LOCATION_INTERFACE.\n");
          cb->start                       = driver_location_start;
@@ -8519,7 +8476,7 @@ bool runloop_environment_cb(unsigned cmd, void *data)
          if (system)
             system->location_cb          = *cb;
 
-         p_rarch->location_driver_active = false;
+         location_st->active             = false;
          break;
       }
 
@@ -9661,6 +9618,10 @@ static void uninit_libretro_symbols(
       *input_st        = input_state_get_ptr();
    audio_driver_state_t 
       *audio_st        = audio_state_get_ptr();
+   camera_driver_state_t 
+      *camera_st       = camera_state_get_ptr();
+   location_driver_state_t 
+      *location_st     = location_state_get_ptr();
 #ifdef HAVE_DYNAMIC
    if (runloop_st->lib_handle)
       dylib_close(runloop_st->lib_handle);
@@ -9689,8 +9650,8 @@ static void uninit_libretro_symbols(
    input_game_focus_free();
    runloop_fastmotion_override_free(&runloop_state);
    runloop_core_options_cb_free(&runloop_state);
-   p_rarch->camera_driver_active      = false;
-   p_rarch->location_driver_active    = false;
+   camera_st->active                             = false;
+   location_st->active                           = false;
 
    /* Core has finished utilising the input driver;
     * reset 'analog input requested' flags */
@@ -10838,88 +10799,6 @@ char* crt_switch_core_name(void)
    return (char*)runloop_state.system.info.library_name;
 }
 
-/* CAMERA */
-
-/**
- * config_get_camera_driver_options:
- *
- * Get an enumerated list of all camera driver names,
- * separated by '|'.
- *
- * Returns: string listing of all camera driver names,
- * separated by '|'.
- **/
-const char *config_get_camera_driver_options(void)
-{
-   return char_list_new_special(STRING_LIST_CAMERA_DRIVERS, NULL);
-}
-
-static bool driver_camera_start(void)
-{
-   struct rarch_state  *p_rarch = &rarch_st;
-   if (  p_rarch->camera_driver &&
-         p_rarch->camera_data   &&
-         p_rarch->camera_driver->start)
-   {
-      settings_t *settings = config_get_ptr();
-      bool camera_allow    = settings->bools.camera_allow;
-      if (camera_allow)
-         return p_rarch->camera_driver->start(p_rarch->camera_data);
-
-      runloop_msg_queue_push(
-            "Camera is explicitly disabled.\n", 1, 180, false,
-            NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
-   }
-   return true;
-}
-
-static void driver_camera_stop(void)
-{
-   struct rarch_state  *p_rarch = &rarch_st;
-   if (     p_rarch->camera_driver
-         && p_rarch->camera_driver->stop
-         && p_rarch->camera_data)
-      p_rarch->camera_driver->stop(p_rarch->camera_data);
-}
-
-static void camera_driver_find_driver(
-      struct rarch_state *p_rarch,
-      settings_t *settings,
-      const char *prefix,
-      bool verbosity_enabled)
-{
-   int i                        = (int)driver_find_index(
-         "camera_driver",
-         settings->arrays.camera_driver);
-
-   if (i >= 0)
-      p_rarch->camera_driver = (const camera_driver_t*)camera_drivers[i];
-   else
-   {
-      if (verbosity_enabled)
-      {
-         unsigned d;
-         RARCH_ERR("Couldn't find any %s named \"%s\"\n", prefix,
-               settings->arrays.camera_driver);
-         RARCH_LOG_OUTPUT("Available %ss are:\n", prefix);
-         for (d = 0; camera_drivers[d]; d++)
-         {
-            if (camera_drivers[d])
-            {
-               RARCH_LOG_OUTPUT("\t%s\n", camera_drivers[d]->ident);
-            }
-         }
-
-         RARCH_WARN("Going to default to first %s...\n", prefix);
-      }
-
-      p_rarch->camera_driver = (const camera_driver_t*)camera_drivers[0];
-
-      if (!p_rarch->camera_driver)
-         retroarch_fail(1, "find_camera_driver()");
-   }
-}
-
 static void driver_adjust_system_rates(
       bool vrr_runloop_enable,
       float video_refresh_rate,
@@ -11051,8 +10930,7 @@ void drivers_init(
       int flags,
       bool verbosity_enabled)
 {
-	struct rarch_state *p_rarch = &rarch_st;
-   runloop_state_t *runloop_st = &runloop_state;
+   runloop_state_t *runloop_st = runloop_state_get_ptr();
    audio_driver_state_t 
       *audio_st                = audio_state_get_ptr();
    input_driver_state_t 
@@ -11062,6 +10940,10 @@ void drivers_init(
 #ifdef HAVE_MENU
    struct menu_state *menu_st  = menu_state_get_ptr();
 #endif
+   camera_driver_state_t 
+      *camera_st               = camera_state_get_ptr();
+   location_driver_state_t 
+      *location_st             = location_state_get_ptr();
    bool video_is_threaded      = VIDEO_DRIVER_IS_THREADED_INTERNAL(video_st);
    gfx_display_t *p_disp       = disp_get_ptr();
 #if defined(HAVE_GFX_WIDGETS)
@@ -11128,33 +11010,34 @@ void drivers_init(
    if (flags & DRIVER_CAMERA_MASK)
    {
       /* Only initialize camera driver if we're ever going to use it. */
-      if (p_rarch->camera_driver_active)
+      if (camera_st->active)
       {
          /* Resource leaks will follow if camera is initialized twice. */
-         if (!p_rarch->camera_data)
+         if (!camera_st->data)
          {
-            camera_driver_find_driver(p_rarch, settings, "camera driver",
-                  verbosity_enabled);
+            if (!camera_driver_find_driver("camera driver",
+                     verbosity_enabled))
+               retroarch_fail(1, "find_camera_driver()");
 
-            if (p_rarch->camera_driver)
+            if (camera_st->driver)
             {
-               p_rarch->camera_data = p_rarch->camera_driver->init(
+               camera_st->data = camera_st->driver->init(
                      *settings->arrays.camera_device ?
                      settings->arrays.camera_device : NULL,
-                     p_rarch->camera_cb.caps,
+                     camera_st->cb.caps,
                      settings->uints.camera_width ?
-                     settings->uints.camera_width : p_rarch->camera_cb.width,
+                     settings->uints.camera_width  : camera_st->cb.width,
                      settings->uints.camera_height ?
-                     settings->uints.camera_height : p_rarch->camera_cb.height);
+                     settings->uints.camera_height : camera_st->cb.height);
 
-               if (!p_rarch->camera_data)
+               if (!camera_st->data)
                {
                   RARCH_ERR("Failed to initialize camera driver. Will continue without camera.\n");
-                  p_rarch->camera_driver_active = false;
+                  camera_st->active = false;
                }
 
-               if (p_rarch->camera_cb.initialized)
-                  p_rarch->camera_cb.initialized();
+               if (camera_st->cb.initialized)
+                  camera_st->cb.initialized();
             }
          }
       }
@@ -11169,10 +11052,10 @@ void drivers_init(
    if (flags & DRIVER_LOCATION_MASK)
    {
       /* Only initialize location driver if we're ever going to use it. */
-      if (p_rarch->location_driver_active)
+      if (location_st->active)
          if (!init_location(&runloop_state.system,
                   settings, verbosity_is_enabled()))
-            p_rarch->location_driver_active = false;
+            location_st->active = false;
    }
 
    core_info_init_current_core();
@@ -11259,10 +11142,11 @@ void drivers_init(
 
 void driver_uninit(int flags)
 {
-   struct rarch_state  *p_rarch = &rarch_st;
    runloop_state_t *runloop_st  = &runloop_state;
    video_driver_state_t 
       *video_st                 = video_state_get_ptr();
+   camera_driver_state_t 
+      *camera_st                = camera_state_get_ptr();
 
    core_info_deinit_list();
    core_info_free_current_core();
@@ -11294,16 +11178,16 @@ void driver_uninit(int flags)
 
    if ((flags & DRIVER_CAMERA_MASK))
    {
-      if (p_rarch->camera_data && p_rarch->camera_driver)
+      if (camera_st->data && camera_st->driver)
       {
-         if (p_rarch->camera_cb.deinitialized)
-            p_rarch->camera_cb.deinitialized();
+         if (camera_st->cb.deinitialized)
+            camera_st->cb.deinitialized();
 
-         if (p_rarch->camera_driver->free)
-            p_rarch->camera_driver->free(p_rarch->camera_data);
+         if (camera_st->driver->free)
+            camera_st->driver->free(camera_st->data);
       }
 
-      p_rarch->camera_data = NULL;
+      camera_st->data = NULL;
    }
 
    if ((flags & DRIVER_BLUETOOTH_MASK))
@@ -11345,9 +11229,11 @@ void driver_uninit(int flags)
 
 static void retroarch_deinit_drivers(struct retro_callbacks *cbs)
 {
-   struct rarch_state  *p_rarch    = &rarch_st;
    input_driver_state_t *input_st  = input_state_get_ptr();
    video_driver_state_t *video_st  = video_state_get_ptr();
+   camera_driver_state_t *camera_st= camera_state_get_ptr();
+   location_driver_state_t 
+      *location_st                 = location_state_get_ptr();
    runloop_state_t     *runloop_st = &runloop_state;
 
 #if defined(HAVE_GFX_WIDGETS)
@@ -11408,13 +11294,13 @@ static void retroarch_deinit_drivers(struct retro_callbacks *cbs)
    menu_driver_destroy(
          menu_state_get_ptr());
 #endif
-   p_rarch->location_driver_active                  = false;
+   location_st->active                              = false;
    destroy_location();
 
    /* Camera */
-   p_rarch->camera_driver_active                    = false;
-   p_rarch->camera_driver                           = NULL;
-   p_rarch->camera_data                             = NULL;
+   camera_st->active                                = false;
+   camera_st->driver                                = NULL;
+   camera_st->data                                  = NULL;
 
    bluetooth_driver_ctl(RARCH_BLUETOOTH_CTL_DESTROY, NULL);
    wifi_driver_ctl(RARCH_WIFI_CTL_DESTROY, NULL);
@@ -13464,8 +13350,9 @@ bool retroarch_main_init(int argc, char *argv[])
             "input driver", verbosity_enabled))
       retroarch_fail(1, "input_driver_find_driver()");
 
-   camera_driver_find_driver(p_rarch, settings,
-         "camera driver", verbosity_enabled);
+   if (!camera_driver_find_driver("camera driver", verbosity_enabled))
+      retroarch_fail(1, "find_camera_driver()");
+
    bluetooth_driver_ctl(RARCH_BLUETOOTH_CTL_FIND_DRIVER, NULL);
    wifi_driver_ctl(RARCH_WIFI_CTL_FIND_DRIVER, NULL);
    location_driver_find_driver(settings,
@@ -15553,6 +15440,7 @@ int runloop_iterate(void)
    audio_driver_state_t               *audio_st = audio_state_get_ptr();
    video_driver_state_t               *video_st = video_state_get_ptr();
    recording_state_t              *recording_st = recording_state_get_ptr();
+   camera_driver_state_t             *camera_st = camera_state_get_ptr();
    settings_t *settings                         = config_get_ptr();
    runloop_state_t *runloop_st                  = &runloop_state;
    unsigned video_frame_delay                   = settings->uints.video_frame_delay;
@@ -15702,13 +15590,13 @@ int runloop_iterate(void)
          = intfstream_tell(input_st->bsv_movie_state_handle->file);
 #endif
 
-   if (  p_rarch->camera_cb.caps &&
-         p_rarch->camera_driver  &&
-         p_rarch->camera_driver->poll &&
-         p_rarch->camera_data)
-      p_rarch->camera_driver->poll(p_rarch->camera_data,
-            p_rarch->camera_cb.frame_raw_framebuffer,
-            p_rarch->camera_cb.frame_opengl_texture);
+   if (     camera_st->cb.caps
+         && camera_st->driver
+         && camera_st->driver->poll
+         && camera_st->data)
+      camera_st->driver->poll(camera_st->data,
+            camera_st->cb.frame_raw_framebuffer,
+            camera_st->cb.frame_opengl_texture);
 
    /* Update binds for analog dpad modes. */
    for (i = 0; i < max_users; i++)
diff --git a/retroarch.h b/retroarch.h
index 7047edd467..b1388e5cec 100644
--- a/retroarch.h
+++ b/retroarch.h
@@ -133,44 +133,6 @@ void bsv_movie_frame_rewind(void);
 
 /* Camera */
 
-typedef struct camera_driver
-{
-   /* FIXME: params for initialization - queries for resolution,
-    * framerate, color format which might or might not be honored. */
-   void *(*init)(const char *device, uint64_t buffer_types,
-         unsigned width, unsigned height);
-
-   void (*free)(void *data);
-
-   bool (*start)(void *data);
-   void (*stop)(void *data);
-
-   /* Polls the camera driver.
-    * Will call the appropriate callback if a new frame is ready.
-    * Returns true if a new frame was handled. */
-   bool (*poll)(void *data,
-         retro_camera_frame_raw_framebuffer_t frame_raw_cb,
-         retro_camera_frame_opengl_texture_t frame_gl_cb);
-
-   const char *ident;
-} camera_driver_t;
-
-extern camera_driver_t camera_v4l2;
-extern camera_driver_t camera_android;
-extern camera_driver_t camera_rwebcam;
-extern camera_driver_t camera_avfoundation;
-
-/**
- * config_get_camera_driver_options:
- *
- * Get an enumerated list of all camera driver names,
- * separated by '|'.
- *
- * Returns: string listing of all camera driver names,
- * separated by '|'.
- **/
-const char* config_get_camera_driver_options(void);
-
 unsigned int retroarch_get_rotation(void);
 
 void retroarch_init_task_queue(void);
diff --git a/runloop.h b/runloop.h
index 4b7974fcd5..17a452cc20 100644
--- a/runloop.h
+++ b/runloop.h
@@ -38,6 +38,7 @@
 
 #include "dynamic.h"
 #include "core_option_manager.h"
+#include "performance_counters.h"
 #include "state_manager.h"
 
 /* Arbitrary twenty subsystems limit */

From dfb0e298c5827b84a58c1a4426a9ac592a1845c1 Mon Sep 17 00:00:00 2001
From: twinaphex <libretro@gmail.com>
Date: Thu, 11 Nov 2021 07:49:43 +0100
Subject: [PATCH 2/3] Buildfix

---
 griffin/griffin.c | 1 +
 retroarch.c       | 3 ---
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/griffin/griffin.c b/griffin/griffin.c
index 6e6323ffa2..ac0f1a24e9 100644
--- a/griffin/griffin.c
+++ b/griffin/griffin.c
@@ -864,6 +864,7 @@ AUDIO RESAMPLER
 /*============================================================
 CAMERA
 ============================================================ */
+#include "../camera/camera_driver.c"
 #if defined(ANDROID)
 #include "../camera/drivers/android.c"
 #elif defined(EMSCRIPTEN)
diff --git a/retroarch.c b/retroarch.c
index 3093155821..e2bb61314d 100644
--- a/retroarch.c
+++ b/retroarch.c
@@ -7340,7 +7340,6 @@ static core_option_manager_t *runloop_init_core_variables(
 bool runloop_environment_cb(unsigned cmd, void *data)
 {
    unsigned p;
-   struct rarch_state *p_rarch            = &rarch_st;
    runloop_state_t *runloop_st            = &runloop_state;
    recording_state_t *recording_st        = recording_state_get_ptr();
 
@@ -9610,8 +9609,6 @@ bool libretro_get_shared_context(void)
 static void uninit_libretro_symbols(
       struct retro_core_t *current_core)
 {
-   struct rarch_state 
-      *p_rarch         = &rarch_st;
    runloop_state_t 
 	   *runloop_st      = &runloop_state;
    input_driver_state_t 

From 62c6d9916315838ca1be8bc1d8444698afb32903 Mon Sep 17 00:00:00 2001
From: twinaphex <libretro@gmail.com>
Date: Thu, 11 Nov 2021 17:53:54 +0100
Subject: [PATCH 3/3] Buildfixes

---
 camera/drivers/android.c      | 1 +
 camera/drivers/rwebcam.c      | 1 +
 camera/drivers/video4linux2.c | 1 +
 3 files changed, 3 insertions(+)

diff --git a/camera/drivers/android.c b/camera/drivers/android.c
index 274d5a8a63..63b63a85a2 100644
--- a/camera/drivers/android.c
+++ b/camera/drivers/android.c
@@ -17,6 +17,7 @@
 
 #include <glsym/glsym.h>
 
+#include "../camera_driver.h"
 #include "../../retroarch.h"
 
 typedef struct android_camera
diff --git a/camera/drivers/rwebcam.c b/camera/drivers/rwebcam.c
index 86f2105355..000afee839 100644
--- a/camera/drivers/rwebcam.c
+++ b/camera/drivers/rwebcam.c
@@ -18,6 +18,7 @@
 
 #include <boolean.h>
 
+#include "../camera_driver.h"
 #include "../../retroarch.h"
 
 /* forward declarations */
diff --git a/camera/drivers/video4linux2.c b/camera/drivers/video4linux2.c
index cc5d57110c..20d9e22b3d 100644
--- a/camera/drivers/video4linux2.c
+++ b/camera/drivers/video4linux2.c
@@ -45,6 +45,7 @@
 
 #include <compat/strl.h>
 
+#include "../camera_driver.h"
 #include "../../retroarch.h"
 #include "../../verbosity.h"