Merge "Remove handling of EV_MSC/MSC_TIMESTAMP in Input"
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0d20b64
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.pyc
diff --git a/cmds/servicemanager/main.cpp b/cmds/servicemanager/main.cpp
index c8ceb42..9f6193b 100644
--- a/cmds/servicemanager/main.cpp
+++ b/cmds/servicemanager/main.cpp
@@ -38,14 +38,13 @@
 
     android::base::InitLogging(nullptr, &android::base::KernelLogger);
 
-    ProcessState::self()->initWithDriver(driver);
-    ProcessState::self()->setThreadPoolMaxThreadCount(0);
-    ProcessState::self()->setCallRestriction(
-        ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);
+    sp<ProcessState> ps = ProcessState::initWithDriver(driver);
+    ps->setThreadPoolMaxThreadCount(0);
+    ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);
 
     sp<ServiceManager> manager = new ServiceManager(std::make_unique<Access>());
     IPCThreadState::self()->setTheContextObject(manager);
-    ProcessState::self()->becomeContextManager(nullptr, nullptr);
+    ps->becomeContextManager(nullptr, nullptr);
 
     IPCThreadState::self()->joinThreadPool();
 
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 2d156df..b25cd7b 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -466,7 +466,7 @@
         }
     }
 
-    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened.  Terminating.");
+    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver '%s' could not be opened.  Terminating.", driver);
 }
 
 ProcessState::~ProcessState()
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index c451780..3e005c9 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -26,28 +26,28 @@
 
 cc_test {
     name: "binderDriverInterfaceTest_IPC_32",
-    srcs: ["binderDriverInterfaceTest.cpp"],
     defaults: ["binder_test_defaults"],
+    srcs: ["binderDriverInterfaceTest.cpp"],
     compile_multilib: "32",
     cflags: ["-DBINDER_IPC_32BIT=1"],
 }
 
 cc_test {
+    name: "binderDriverInterfaceTest",
+    defaults: ["binder_test_defaults"],
     product_variables: {
         binder32bit: {
             cflags: ["-DBINDER_IPC_32BIT=1"],
         },
     },
 
-    name: "binderDriverInterfaceTest",
     srcs: ["binderDriverInterfaceTest.cpp"],
-    defaults: ["binder_test_defaults"],
 }
 
 cc_test {
     name: "binderValueTypeTest",
-    srcs: ["binderValueTypeTest.cpp"],
     defaults: ["binder_test_defaults"],
+    srcs: ["binderValueTypeTest.cpp"],
     shared_libs: [
         "libbinder",
         "libutils",
@@ -56,8 +56,8 @@
 
 cc_test {
     name: "binderLibTest_IPC_32",
-    srcs: ["binderLibTest.cpp"],
     defaults: ["binder_test_defaults"],
+    srcs: ["binderLibTest.cpp"],
     shared_libs: [
         "libbinder",
         "libutils",
@@ -67,14 +67,14 @@
 }
 
 cc_test {
+    name: "binderLibTest",
+    defaults: ["binder_test_defaults"],
     product_variables: {
         binder32bit: {
             cflags: ["-DBINDER_IPC_32BIT=1"],
         },
     },
 
-    defaults: ["binder_test_defaults"],
-    name: "binderLibTest",
     srcs: ["binderLibTest.cpp"],
     shared_libs: [
         "libbinder",
@@ -84,8 +84,8 @@
 
 cc_test {
     name: "binderThroughputTest",
-    srcs: ["binderThroughputTest.cpp"],
     defaults: ["binder_test_defaults"],
+    srcs: ["binderThroughputTest.cpp"],
     shared_libs: [
         "libbinder",
         "libutils",
@@ -101,8 +101,8 @@
 
 cc_test {
     name: "binderTextOutputTest",
-    srcs: ["binderTextOutputTest.cpp"],
     defaults: ["binder_test_defaults"],
+    srcs: ["binderTextOutputTest.cpp"],
     shared_libs: [
         "libbinder",
         "libutils",
@@ -112,8 +112,8 @@
 
 cc_test {
     name: "schd-dbg",
-    srcs: ["schd-dbg.cpp"],
     defaults: ["binder_test_defaults"],
+    srcs: ["schd-dbg.cpp"],
     shared_libs: [
         "libbinder",
         "libutils",
@@ -123,8 +123,8 @@
 
 cc_test {
     name: "binderSafeInterfaceTest",
-    srcs: ["binderSafeInterfaceTest.cpp"],
     defaults: ["binder_test_defaults"],
+    srcs: ["binderSafeInterfaceTest.cpp"],
 
     cppflags: [
         "-Weverything",
diff --git a/services/surfaceflinger/Scheduler/DispSyncSource.cpp b/services/surfaceflinger/Scheduler/DispSyncSource.cpp
index 026b557..5faf46e 100644
--- a/services/surfaceflinger/Scheduler/DispSyncSource.cpp
+++ b/services/surfaceflinger/Scheduler/DispSyncSource.cpp
@@ -78,6 +78,10 @@
     // Normalize phaseOffset to [-period, period)
     const int numPeriods = phaseOffset / period;
     phaseOffset -= numPeriods * period;
+    if (mPhaseOffset == phaseOffset) {
+        return;
+    }
+
     mPhaseOffset = phaseOffset;
     tracePhaseOffset();
 
diff --git a/services/surfaceflinger/Scheduler/LayerInfo.cpp b/services/surfaceflinger/Scheduler/LayerInfo.cpp
index beddb9b..e782dd5 100644
--- a/services/surfaceflinger/Scheduler/LayerInfo.cpp
+++ b/services/surfaceflinger/Scheduler/LayerInfo.cpp
@@ -50,7 +50,8 @@
     // Ignore time diff that are too high - those are stale values
     if (timeDiff > OBSOLETE_TIME_EPSILON_NS.count()) return;
     const nsecs_t refreshDuration = (timeDiff > 0) ? timeDiff : mMinRefreshDuration;
-    mRefreshRateHistory.insertRefreshRate(refreshDuration);
+    const int fps = 1e9f / refreshDuration;
+    mRefreshRateHistory.insertRefreshRate(fps);
 }
 
 } // namespace scheduler
diff --git a/services/surfaceflinger/Scheduler/LayerInfo.h b/services/surfaceflinger/Scheduler/LayerInfo.h
index 2c50053..66df9dc 100644
--- a/services/surfaceflinger/Scheduler/LayerInfo.h
+++ b/services/surfaceflinger/Scheduler/LayerInfo.h
@@ -46,7 +46,7 @@
     public:
         explicit RefreshRateHistory(nsecs_t minRefreshDuration)
               : mMinRefreshDuration(minRefreshDuration) {}
-        void insertRefreshRate(nsecs_t refreshRate) {
+        void insertRefreshRate(int refreshRate) {
             mElements.push_back(refreshRate);
             if (mElements.size() > HISTORY_SIZE) {
                 mElements.pop_front();
@@ -54,13 +54,13 @@
         }
 
         float getRefreshRateAvg() const {
-            nsecs_t refreshDuration = mMinRefreshDuration;
-            if (mElements.size() > 0) {
-                refreshDuration = scheduler::calculate_mean(mElements);
+            if (mElements.empty()) {
+                return 1e9f / mMinRefreshDuration;
             }
 
-            return 1e9f / refreshDuration;
+            return scheduler::calculate_mean(mElements);
         }
+
         void clearHistory() { mElements.clear(); }
 
     private:
diff --git a/services/surfaceflinger/Scheduler/VSyncModulator.cpp b/services/surfaceflinger/Scheduler/VSyncModulator.cpp
index d452c19..7a3bf8e 100644
--- a/services/surfaceflinger/Scheduler/VSyncModulator.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncModulator.cpp
@@ -129,29 +129,16 @@
 
 void VSyncModulator::updateOffsetsLocked() {
     const Offsets desired = getNextOffsets();
-    const Offsets current = mOffsets;
 
-    bool changed = false;
-    if (desired.sf != current.sf) {
-        if (mSfConnectionHandle != nullptr) {
-            mScheduler->setPhaseOffset(mSfConnectionHandle, desired.sf);
-        } else if (mSfEventThread != nullptr) {
-            mSfEventThread->setPhaseOffset(desired.sf);
-        }
-        changed = true;
-    }
-    if (desired.app != current.app) {
-        if (mAppConnectionHandle != nullptr) {
-            mScheduler->setPhaseOffset(mAppConnectionHandle, desired.app);
-        } else if (mAppEventThread != nullptr) {
-            mAppEventThread->setPhaseOffset(desired.app);
-        }
-        changed = true;
+    if (mSfConnectionHandle != nullptr) {
+        mScheduler->setPhaseOffset(mSfConnectionHandle, desired.sf);
     }
 
-    if (changed) {
-        flushOffsets();
+    if (mAppConnectionHandle != nullptr) {
+        mScheduler->setPhaseOffset(mAppConnectionHandle, desired.app);
     }
+
+    flushOffsets();
 }
 
 void VSyncModulator::flushOffsets() {
diff --git a/services/surfaceflinger/Scheduler/VSyncModulator.h b/services/surfaceflinger/Scheduler/VSyncModulator.h
index 10cf8e6..ddbd221 100644
--- a/services/surfaceflinger/Scheduler/VSyncModulator.h
+++ b/services/surfaceflinger/Scheduler/VSyncModulator.h
@@ -68,12 +68,6 @@
     void setPhaseOffsets(Offsets early, Offsets earlyGl, Offsets late,
                          nsecs_t thresholdForNextVsync) EXCLUDES(mMutex);
 
-    // Sets handles to the SF and app event threads.
-    void setEventThreads(EventThread* sfEventThread, EventThread* appEventThread) {
-        mSfEventThread = sfEventThread;
-        mAppEventThread = appEventThread;
-    }
-
     // Sets the scheduler and vsync connection handlers.
     void setSchedulerAndHandles(Scheduler* scheduler,
                                 Scheduler::ConnectionHandle* appConnectionHandle,
@@ -121,9 +115,6 @@
     std::unordered_map<OffsetType, Offsets> mOffsetMap GUARDED_BY(mMutex);
     nsecs_t mThresholdForNextVsync;
 
-    EventThread* mSfEventThread = nullptr;
-    EventThread* mAppEventThread = nullptr;
-
     Scheduler* mScheduler = nullptr;
     Scheduler::ConnectionHandle* mAppConnectionHandle = nullptr;
     Scheduler::ConnectionHandle* mSfConnectionHandle = nullptr;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 6ebfc0d..47c17d0 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1477,7 +1477,7 @@
     *compositorTiming = getBE().mCompositorTiming;
 }
 
-bool SurfaceFlinger::isDisplayConfigAllowed(int32_t configId) {
+bool SurfaceFlinger::isDisplayConfigAllowed(int32_t configId) const {
     return mAllowedDisplayConfigs.empty() || mAllowedDisplayConfigs.count(configId);
 }
 
@@ -4710,11 +4710,9 @@
     StringAppendF(&result, "+  Smart 90 for video detection: %s\n\n",
                   mUseSmart90ForVideo ? "on" : "off");
     StringAppendF(&result, "Allowed Display Configs: ");
-    for (int32_t configId : mAllowedDisplayConfigs) {
-        for (auto refresh : mRefreshRateConfigs.getRefreshRates()) {
-            if (refresh.second && refresh.second->configId == configId) {
-                StringAppendF(&result, "%dHz, ", refresh.second->fps);
-            }
+    for (auto refresh : mRefreshRateConfigs.getRefreshRates()) {
+        if (refresh.second && isDisplayConfigAllowed(refresh.second->configId)) {
+            StringAppendF(&result, "%dHz, ", refresh.second->fps);
         }
     }
     StringAppendF(&result, "(config override by backdoor: %s)\n\n",
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index f7b7410..fa801af 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -813,7 +813,7 @@
     // the desired refresh rate.
     void setRefreshRateTo(RefreshRateType, Scheduler::ConfigEvent event) REQUIRES(mStateLock);
 
-    bool isDisplayConfigAllowed(int32_t configId) REQUIRES(mStateLock);
+    bool isDisplayConfigAllowed(int32_t configId) const REQUIRES(mStateLock);
 
     /*
      * Display identification
diff --git a/vulkan/scripts/code_generator.py b/vulkan/scripts/code_generator.py
old mode 100644
new mode 100755
index 91c0d30..9e14b28
--- a/vulkan/scripts/code_generator.py
+++ b/vulkan/scripts/code_generator.py
@@ -19,8 +19,11 @@
 
 import generator_common as gencom
 import api_generator as apigen
+import driver_generator as drivergen
 
 if __name__ == '__main__':
   gencom.parseVulkanRegistry()
   apigen.api_genh()
   apigen.api_gencpp()
+  drivergen.driver_genh()
+  drivergen.driver_gencpp()
diff --git a/vulkan/scripts/driver_generator.py b/vulkan/scripts/driver_generator.py
new file mode 100644
index 0000000..92326ca
--- /dev/null
+++ b/vulkan/scripts/driver_generator.py
@@ -0,0 +1,393 @@
+#!/usr/bin/env python3
+#
+# Copyright 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# This script provides the functions for generating the
+# vulkan driver framework directly from the vulkan registry (vk.xml).
+
+import generator_common as gencom
+import os
+
+interceptedExtensions = [
+  'VK_ANDROID_native_buffer',
+  'VK_EXT_debug_report',
+  'VK_EXT_hdr_metadata',
+  'VK_EXT_swapchain_colorspace',
+  'VK_GOOGLE_display_timing',
+  'VK_KHR_android_surface',
+  'VK_KHR_incremental_present',
+  'VK_KHR_shared_presentable_image',
+  'VK_KHR_surface',
+  'VK_KHR_swapchain',
+  'VK_KHR_get_surface_capabilities2'
+]
+
+knownExtensions = interceptedExtensions + [
+  'VK_KHR_get_physical_device_properties2',
+  'VK_ANDROID_external_memory_android_hardware_buffer',
+  'VK_KHR_bind_memory2'
+]
+
+def defineProcHookType(f):
+  f.write ("""struct ProcHook {
+    enum Type {
+        GLOBAL,
+        INSTANCE,
+        DEVICE,
+    };
+    enum Extension {\n""")
+  for exts in knownExtensions:
+    f.write (gencom.clang_off_spaces*2 + exts[3:] + ',\n')
+  f.write ('\n')
+  f.write (gencom.clang_off_spaces*2 + """EXTENSION_CORE,  // valid bit
+        EXTENSION_COUNT,
+        EXTENSION_UNKNOWN,
+    };
+
+    const char* name;
+    Type type;
+    Extension extension;
+
+    PFN_vkVoidFunction proc;
+    PFN_vkVoidFunction checked_proc;  // always nullptr for non-device hooks
+};\n\n""")
+
+def isExtensionIntercepted(extensionName):
+  if extensionName in interceptedExtensions:
+    return True
+  return False
+
+def isDriverTableEntry(functionName):
+  switchCase = {
+    # Create functions of dispatchable objects
+    'vkCreateDevice' : True,
+    'vkGetDeviceQueue' : True,
+    'vkGetDeviceQueue2' : True,
+    'vkAllocateCommandBuffers' : True,
+
+    # Destroy functions of dispatchable objects
+    'vkDestroyInstance' : True,
+    'vkDestroyDevice' : True,
+
+    # Enumeration of extensions
+    'vkEnumerateDeviceExtensionProperties' : True,
+
+    # We cache physical devices in loader.cpp
+    'vkEnumeratePhysicalDevices' : True,
+    'vkEnumeratePhysicalDeviceGroups' : True,
+
+    'vkGetInstanceProcAddr' : True,
+    'vkGetDeviceProcAddr' : True,
+
+    # VK_KHR_swapchain->VK_ANDROID_native_buffer translation
+    'vkCreateImage' : True,
+    'vkDestroyImage' : True,
+
+    'vkGetPhysicalDeviceProperties' : True,
+    'vkGetPhysicalDeviceProperties2' : True,
+    'vkGetPhysicalDeviceProperties2KHR' : True,
+
+    # VK_KHR_swapchain v69 requirement
+    'vkBindImageMemory2' : True,
+    'vkBindImageMemory2KHR' : True
+  }
+  if gencom.isFunctionSupported(functionName):
+    if functionName in switchCase:
+      return True
+    if functionName in gencom.extensionsDict:
+      if gencom.extensionsDict[functionName] == 'VK_ANDROID_native_buffer' or gencom.extensionsDict[functionName] == 'VK_EXT_debug_report':
+        return True
+  return False
+
+def isInstanceDriverTableEntry(functionName):
+  if isDriverTableEntry(functionName) and gencom.isInstanceDispatched(functionName):
+    return True
+  return False
+
+def isDeviceDriverTableEntry(functionName):
+  if isDriverTableEntry(functionName) and gencom.isDeviceDispatched(functionName):
+    return True
+  return False
+
+def driver_genh():
+  header = """#ifndef LIBVULKAN_DRIVER_GEN_H
+#define LIBVULKAN_DRIVER_GEN_H
+
+#include <vulkan/vk_android_native_buffer.h>
+#include <vulkan/vulkan.h>
+
+#include <bitset>
+
+namespace vulkan {
+namespace driver {\n\n"""
+  genfile = os.path.join(os.path.dirname(__file__),'..','libvulkan','driver_gen2.h')
+  with open(genfile, 'w') as f:
+    f.write (gencom.copyright)
+    f.write (gencom.warning)
+    f.write (header)
+    defineProcHookType(f)
+    f.write ('struct InstanceDriverTable {\n')
+    gencom.clang_off(f, 1)
+    for cmds in gencom.allCommandsList:
+      if isInstanceDriverTableEntry(cmds):
+        f.write (gencom.clang_off_spaces + 'PFN_' + cmds + ' ' + cmds[2:] + ';\n')
+    gencom.clang_on(f, 1)
+    f.write ('};\n\n')
+    f.write ('struct DeviceDriverTable {\n')
+    gencom.clang_off(f,1)
+    for cmds in gencom.allCommandsList:
+      if isDeviceDriverTableEntry(cmds):
+        f.write (gencom.clang_off_spaces + 'PFN_' + cmds + ' ' + cmds[2:] + ';\n')
+    gencom.clang_on(f,1)
+    f.write ('};\n\n')
+    f.write ("""const ProcHook* GetProcHook(const char* name);
+ProcHook::Extension GetProcHookExtension(const char* name);
+
+bool InitDriverTable(VkInstance instance,
+                     PFN_vkGetInstanceProcAddr get_proc,
+                     const std::bitset<ProcHook::EXTENSION_COUNT>& extensions);
+bool InitDriverTable(VkDevice dev,
+                     PFN_vkGetDeviceProcAddr get_proc,
+                     const std::bitset<ProcHook::EXTENSION_COUNT>& extensions);
+
+}  // namespace driver
+}  // namespace vulkan
+
+#endif  // LIBVULKAN_DRIVER_TABLE_H\n""")
+
+def isIntercepted(functionName):
+  switchCase = {
+    # Create functions of dispatchable objects
+    'vkCreateInstance' : True,
+    'vkCreateDevice' : True,
+    'vkEnumeratePhysicalDevices' : True,
+    'vkEnumeratePhysicalDeviceGroups' : True,
+    'vkGetDeviceQueue' : True,
+    'vkGetDeviceQueue2' : True,
+    'vkAllocateCommandBuffers' : True,
+
+    # Destroy functions of dispatchable objects
+    'vkDestroyInstance' : True,
+    'vkDestroyDevice' : True,
+
+    # Enumeration of extensions
+    'vkEnumerateInstanceExtensionProperties' : True,
+    'vkEnumerateDeviceExtensionProperties' : True,
+
+    'vkGetInstanceProcAddr' : True,
+    'vkGetDeviceProcAddr' : True,
+
+    # VK_KHR_swapchain v69 requirement
+    'vkBindImageMemory2' : True,
+    'vkBindImageMemory2KHR' : True
+  }
+  if gencom.isFunctionSupported(functionName):
+    if functionName in switchCase:
+      return switchCase[functionName]
+
+    if functionName in gencom.extensionsDict:
+      return isExtensionIntercepted(gencom.extensionsDict[functionName])
+  return False
+
+def needProcHookStub(functionName):
+  if isIntercepted(functionName) and gencom.isDeviceDispatched(functionName):
+    if functionName in gencom.extensionsDict:
+      if not gencom.isExtensionInternal(gencom.extensionsDict[functionName]):
+        return True
+  return False
+
+def defineInitProc(name, f):
+  f.write ('#define UNLIKELY(expr) __builtin_expect((expr), 0)\n')
+  f.write ('\n')
+  f.write ("""#define INIT_PROC(required, obj, proc)                                 \\
+    do {                                                               \\
+        data.""" + name + """.proc =                                             \\
+            reinterpret_cast<PFN_vk##proc>(get_proc(obj, "vk" #proc)); \\
+        if (UNLIKELY(required && !data.""" + name + """.proc)) {                 \\
+            ALOGE("missing " #obj " proc: vk" #proc);                  \\
+            success = false;                                           \\
+        }                                                              \\
+    } while (0)\n\n""")
+
+def defineInitProcExt(f):
+  f.write ("""#define INIT_PROC_EXT(ext, required, obj, proc) \\
+    do {                                        \\
+        if (extensions[ProcHook::ext])          \\
+            INIT_PROC(required, obj, proc);     \\
+    } while (0)\n\n""")
+
+def defineProcHookStub(functionName, f):
+  if needProcHookStub(functionName):
+    ext_name = gencom.extensionsDict[functionName]
+    base_name = functionName[2:]
+    paramList = [''.join(i) for i in gencom.paramDict[functionName]]
+    p0 = gencom.paramDict[functionName][0][1]
+    f.write ('VKAPI_ATTR ' + gencom.returnTypeDict[functionName] + ' checked' + base_name + '(' + ', '.join(paramList) + ') {\n')
+    ext_hook = 'ProcHook::' + ext_name[3:]
+
+    f.write (gencom.clang_off_spaces + 'if (GetData(' + p0 + ').hook_extensions[' + ext_hook + ']) {\n')
+    f.write (gencom.clang_off_spaces *2)
+    if gencom.returnTypeDict[functionName] != 'void':
+      f.write ('return ')
+    paramNames = [''.join(i[1]) for i in gencom.paramDict[functionName]]
+    f.write (base_name + '(' + ', '.join(paramNames) + ');\n')
+    f.write (gencom.clang_off_spaces + '} else {\n')
+    f.write (gencom.clang_off_spaces*2 + 'Logger(' + p0 + ').Err(' + p0 + ', \"' + ext_name + ' not enabled. ' + functionName + ' not executed.\");\n')
+    if gencom.returnTypeDict[functionName] != 'void':
+      f.write (gencom.clang_off_spaces*2 + 'return VK_SUCCESS;\n')
+    f.write (gencom.clang_off_spaces + '}\n')
+    f.write ('}\n\n')
+
+def defineGlobalProcHook(functionName, f):
+  base_name = functionName[2:]
+  assert (functionName not in gencom.extensionsDict)
+  f.write (gencom.clang_off_spaces + '{\n' + gencom.clang_off_spaces*2 + '\"' + functionName + '\",\n' + gencom.clang_off_spaces*2)
+  f.write ("""ProcHook::GLOBAL,
+        ProcHook::EXTENSION_CORE,
+        reinterpret_cast<PFN_vkVoidFunction>(""" + base_name  + """),
+        nullptr,
+    },\n""")
+
+def defineInstanceProcHook(functionName, f):
+  base_name = functionName[2:]
+  f.write (gencom.clang_off_spaces + '{\n')
+  f.write (gencom.clang_off_spaces*2 + '\"' + functionName + '\",\n')
+  f.write (gencom.clang_off_spaces*2 + 'ProcHook::INSTANCE,\n')
+
+  if functionName in gencom.extensionsDict:
+    ext_name = gencom.extensionsDict[functionName]
+    f.write (gencom.clang_off_spaces*2 + 'ProcHook::' + ext_name[3:] + ',\n')
+    if gencom.isExtensionInternal(ext_name):
+      f.write (gencom.clang_off_spaces*2 + 'nullptr,\n' + gencom.clang_off_spaces*2 + 'nullptr,\n')
+    else:
+      f.write (gencom.clang_off_spaces*2 + 'reinterpret_cast<PFN_vkVoidFunction>(' + base_name + '),\n' + gencom.clang_off_spaces*2 + 'nullptr,\n')
+
+  else:
+    f.write (gencom.clang_off_spaces*2 + """ProcHook::EXTENSION_CORE,
+        reinterpret_cast<PFN_vkVoidFunction>(""" + base_name + """),
+        nullptr,\n""")
+
+  f.write (gencom.clang_off_spaces + '},\n')
+
+def defineDeviceProcHook(functionName, f):
+  base_name = functionName[2:]
+  f.write (gencom.clang_off_spaces + '{\n')
+  f.write (gencom.clang_off_spaces*2 + '\"' + functionName + '\",\n')
+  f.write (gencom.clang_off_spaces*2 + 'ProcHook::DEVICE,\n')
+
+  if functionName in gencom.extensionsDict:
+    ext_name = gencom.extensionsDict[functionName]
+    f.write (gencom.clang_off_spaces*2 + 'ProcHook::' + ext_name[3:] + ',\n')
+    if gencom.isExtensionInternal(ext_name):
+      f.write (gencom.clang_off_spaces*2 + 'nullptr,\n' + gencom.clang_off_spaces*2 + 'nullptr,\n')
+    else:
+      f.write (gencom.clang_off_spaces*2 + 'reinterpret_cast<PFN_vkVoidFunction>(' + base_name + '),\n' + gencom.clang_off_spaces*2 + 'reinterpret_cast<PFN_vkVoidFunction>(checked' + base_name + '),\n')
+
+  else:
+    f.write (gencom.clang_off_spaces*2 + """ProcHook::EXTENSION_CORE,
+        reinterpret_cast<PFN_vkVoidFunction>(""" + base_name + """),
+        nullptr,\n""")
+
+  f.write (gencom.clang_off_spaces + '},\n')
+
+def driver_gencpp():
+  header = """#include <log/log.h>
+#include <string.h>
+
+#include <algorithm>
+
+#include "driver.h"
+
+namespace vulkan {
+namespace driver {
+
+namespace {
+
+// clang-format off\n\n"""
+
+  genfile = os.path.join(os.path.dirname(__file__),'..','libvulkan','driver_gen2.cpp')
+
+  with open(genfile, 'w') as f:
+    f.write (gencom.copyright)
+    f.write (gencom.warning)
+    f.write (header)
+
+    for cmds in gencom.allCommandsList:
+      defineProcHookStub(cmds, f)
+    gencom.clang_on(f, 0)
+    f.write ('\n')
+
+    f.write ('const ProcHook g_proc_hooks[] = {\n')
+    gencom.clang_off(f, 1)
+    sortedCommandsList = sorted(gencom.allCommandsList)
+    for cmds in sortedCommandsList:
+      if isIntercepted(cmds):
+        if gencom.isGloballyDispatched(cmds):
+          defineGlobalProcHook(cmds, f)
+        elif gencom.isInstanceDispatched(cmds):
+          defineInstanceProcHook(cmds, f)
+        elif gencom.isDeviceDispatched(cmds):
+          defineDeviceProcHook(cmds, f)
+    gencom.clang_on(f, 1)
+    f.write ('};\n\n}  // namespace\n\n')
+
+    f.write ("""const ProcHook* GetProcHook(const char* name) {
+    const auto& begin = g_proc_hooks;
+    const auto& end =
+        g_proc_hooks + sizeof(g_proc_hooks) / sizeof(g_proc_hooks[0]);
+    const auto hook = std::lower_bound(
+        begin, end, name,
+        [](const ProcHook& e, const char* n) { return strcmp(e.name, n) < 0; });
+    return (hook < end && strcmp(hook->name, name) == 0) ? hook : nullptr;
+}\n\n""")
+
+    f.write ('ProcHook::Extension GetProcHookExtension(const char* name) {\n')
+    gencom.clang_off(f, 1)
+    for exts in knownExtensions:
+      f.write (gencom.clang_off_spaces + 'if (strcmp(name, \"' + exts + '\") == 0) return ProcHook::' + exts[3:] + ';\n')
+    gencom.clang_on(f, 1)
+    f.write (gencom.clang_off_spaces + 'return ProcHook::EXTENSION_UNKNOWN;\n')
+    f.write ('}\n\n')
+
+    defineInitProc('driver', f)
+    defineInitProcExt(f)
+
+    f.write ("""bool InitDriverTable(VkInstance instance,
+                     PFN_vkGetInstanceProcAddr get_proc,
+                     const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) {
+    auto& data = GetData(instance);
+    bool success = true;\n\n""")
+    gencom.clang_off(f, 1)
+    for cmds in gencom.allCommandsList:
+      if isInstanceDriverTableEntry(cmds):
+        gencom.initProc(cmds, f)
+    gencom.clang_on(f, 1)
+    f.write ('\n' + gencom.clang_off_spaces + 'return success;\n')
+    f.write ('}\n\n')
+
+    f.write ("""bool InitDriverTable(VkDevice dev,
+                     PFN_vkGetDeviceProcAddr get_proc,
+                     const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) {
+    auto& data = GetData(dev);
+    bool success = true;\n\n""")
+    gencom.clang_off(f, 1)
+    for cmds in gencom.allCommandsList:
+      if isDeviceDriverTableEntry(cmds):
+        gencom.initProc(cmds, f)
+    gencom.clang_on(f, 1)
+    f.write ('\n' + gencom.clang_off_spaces + 'return success;\n')
+    f.write ('}\n\n}  // namespace driver\n}  // namespace vulkan\n\n')
+    gencom.clang_on(f, 0)
+
diff --git a/vulkan/scripts/generator_common.py b/vulkan/scripts/generator_common.py
index 313357d..51ad6f5 100644
--- a/vulkan/scripts/generator_common.py
+++ b/vulkan/scripts/generator_common.py
@@ -61,7 +61,11 @@
     'VK_NV_win32_keyed_mutex',
     'VK_EXT_metal_surface', #not present in vulkan.api
     'VK_NVX_image_view_handle', #not present in vulkan.api
-    'VK_NV_cooperative_matrix' #not present in vulkan.api
+    'VK_NV_cooperative_matrix', #not present in vulkan.api
+    'VK_EXT_headless_surface', #not present in vulkan.api
+    'VK_GGP_stream_descriptor_surface', #not present in vulkan.api
+    'VK_NV_coverage_reduction_mode', #not present in vulkan.api
+    'VK_EXT_full_screen_exclusive' #not present in vulkan.api
 ]
 
 exportedExtensions = [
@@ -71,6 +75,11 @@
     'VK_ANDROID_external_memory_android_hardware_buffer'
 ]
 
+def isExtensionInternal(extensionName):
+  if extensionName == 'VK_ANDROID_native_buffer':
+    return True
+  return False
+
 def isFunctionSupported(functionName):
   if functionName not in extensionsDict:
     return True
@@ -167,6 +176,7 @@
           aliasDict[fnName] = alias
           allCommandsList.append(fnName)
           paramDict[fnName] = paramDict[alias].copy()
+          returnTypeDict[fnName] = returnTypeDict[alias]
         for params in command:
           if(params.tag == 'param'):
             paramtype = ""
@@ -208,6 +218,19 @@
                 if apiversion != "":
                   versionDict[commandname] = apiversion
 
+  # TODO(adsrini): http://b/136570819
+  extensionsDict['vkGetSwapchainGrallocUsage2ANDROID'] = 'VK_ANDROID_native_buffer'
+  allCommandsList.append('vkGetSwapchainGrallocUsage2ANDROID')
+  returnTypeDict['vkGetSwapchainGrallocUsage2ANDROID'] = 'VkResult'
+  paramDict['vkGetSwapchainGrallocUsage2ANDROID'] = [
+    ('VkDevice ', 'device', None),
+    ('VkFormat ', 'format', None),
+    ('VkImageUsageFlags', 'imageUsage', None),
+    ('VkSwapchainImageUsageFlagsANDROID ', 'swapchainImageUsage', None),
+    ('u64* ', 'grallocConsumerUsage', None),
+    ('u64* ', 'grallocProducerUsage', None)
+  ]
+
   for feature in root.iter('feature'):
     apiversion = feature.get('name')
     for req in feature:
@@ -226,6 +249,8 @@
 
   if name in versionDict and versionDict[name] == 'VK_VERSION_1_1':
     f.write('false, ')
+  elif name == 'vkGetSwapchainGrallocUsageANDROID' or name == 'vkGetSwapchainGrallocUsage2ANDROID': # optional in vulkan.api
+    f.write('false, ')
   else:
     f.write('true, ')