• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python3 -i
2#
3# Copyright (c) 2013-2018 The Khronos Group Inc.
4# Copyright (c) 2013-2018 Google Inc.
5#
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10#     http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17
18import os, re, sys
19from generator import *
20
21import cereal
22from cereal.wrapperdefs import VULKAN_STREAM_TYPE
23from cereal.wrapperdefs import VULKAN_STREAM_TYPE_GUEST
24
25# CerealGenerator - generates set of driver sources
26# while being agnostic to the stream implementation
27
28copyrightHeader = """// Copyright (C) 2018 The Android Open Source Project
29// Copyright (C) 2018 Google Inc.
30//
31// Licensed under the Apache License, Version 2.0 (the "License");
32// you may not use this file except in compliance with the License.
33// You may obtain a copy of the License at
34//
35// http://www.apache.org/licenses/LICENSE-2.0
36//
37// Unless required by applicable law or agreed to in writing, software
38// distributed under the License is distributed on an "AS IS" BASIS,
39// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
40// See the License for the specific language governing permissions and
41// limitations under the License.
42"""
43
44autogeneratedHeaderTemplate = """
45// Autogenerated module %s
46// %s
47// Please do not modify directly;
48// re-run generate-vulkan-sources.sh,
49// or directly from Python by defining:
50// VULKAN_REGISTRY_XML_DIR : Directory containing genvk.py and vk.xml
51// CEREAL_OUTPUT_DIR: Where to put the generated sources.
52// python3 $VULKAN_REGISTRY_XML_DIR/genvk.py -registry $VULKAN_REGISTRY_XML_DIR/vk.xml cereal -o $CEREAL_OUTPUT_DIR
53"""
54
55autogeneratedMkTemplate = """
56# Autogenerated makefile
57# %s
58# Please do not modify directly;
59# re-run generate-vulkan-sources.sh,
60# or directly from Python by defining:
61# VULKAN_REGISTRY_XML_DIR : Directory containing genvk.py and vk.xml
62# CEREAL_OUTPUT_DIR: Where to put the generated sources.
63# python3 $VULKAN_REGISTRY_XML_DIR/genvk.py -registry $VULKAN_REGISTRY_XML_DIR/vk.xml cereal -o $CEREAL_OUTPUT_DIR
64"""
65
66def banner_command(argv):
67    """Return sanitized command-line description.
68       |argv| must be a list of command-line parameters, e.g. sys.argv.
69       Return a string corresponding to the command, with platform-specific
70       paths removed."""
71
72    def makeRelative(someArg):
73        if os.path.exists(someArg):
74            # replace '\' with '/' to ensure the same output when running on Windows
75            return os.path.relpath(someArg).replace("\\", "/")
76        return someArg
77
78    return ' '.join(map(makeRelative, argv))
79
80suppressEnabled = False
81suppressExceptModule = None
82
83def envGetOrDefault(key, default=None):
84    if key in os.environ:
85        return os.environ[key]
86    print("envGetOrDefault: notfound: %s" % key)
87    return default
88
89def init_suppress_option():
90    global suppressEnabled
91    global suppressExceptModule
92
93    if "ANDROID_EMU_VK_CEREAL_SUPPRESS" in os.environ:
94        option = os.environ["ANDROID_EMU_VK_CEREAL_SUPPRESS"]
95
96        if option != "":
97            suppressExceptModule = option
98            suppressEnabled = True
99            print("suppressEnabled: %s" % suppressExceptModule)
100
101# ---- methods overriding base class ----
102# beginFile(genOpts)
103# endFile()
104# beginFeature(interface, emit)
105# endFeature()
106# genType(typeinfo,name)
107# genStruct(typeinfo,name)
108# genGroup(groupinfo,name)
109# genEnum(enuminfo, name)
110# genCmd(cmdinfo)
111class CerealGenerator(OutputGenerator):
112
113    """Generate serialization code"""
114    def __init__(self, errFile = sys.stderr,
115                       warnFile = sys.stderr,
116                       diagFile = sys.stdout):
117        OutputGenerator.__init__(self, errFile, warnFile, diagFile)
118
119        init_suppress_option()
120
121        self.typeInfo = cereal.VulkanTypeInfo()
122
123        self.modules = {}
124        self.protos = {}
125        self.moduleList = []
126        self.protoList = []
127
128        self.wrappers = []
129
130        self.codegen = cereal.CodeGen()
131
132        self.guestBaseLibDirPrefix = \
133            envGetOrDefault("VK_CEREAL_GUEST_BASELIB_PREFIX", "android/base")
134        self.baseLibDirPrefix = \
135            envGetOrDefault("VK_CEREAL_BASELIB_PREFIX", "android/base")
136        self.baseLibLinkName = \
137            envGetOrDefault("VK_CEREAL_BASELIB_LINKNAME", "android-emu-base")
138
139        default_guest_abs_encoder_destination = \
140            os.path.join(
141                os.getcwd(),
142                "..", "..",
143                "device", "generic", "goldfish-opengl",
144                "system", "vulkan_enc")
145        self.guest_abs_encoder_destination = \
146            envGetOrDefault("VK_CEREAL_GUEST_ENCODER_DIR",
147                            default_guest_abs_encoder_destination)
148
149        default_guest_abs_hal_destination = \
150            os.path.join(
151                os.getcwd(),
152                "..", "..",
153                "device", "generic", "goldfish-opengl",
154                "system", "vulkan")
155        self.guest_abs_hal_destination = \
156            envGetOrDefault("VK_CEREAL_GUEST_HAL_DIR",
157                            default_guest_abs_hal_destination)
158
159        default_host_abs_decoder_destination = \
160            os.path.join(
161                os.getcwd(),
162                "android", "android-emugl", "host",
163                "libs", "libOpenglRender", "vulkan")
164        self.host_abs_decoder_destination = \
165            envGetOrDefault("VK_CEREAL_HOST_DECODER_DIR",
166                            default_host_abs_decoder_destination)
167
168        default_host_include_dir = \
169            os.path.join(
170                os.getcwd(),
171                "android", "android-emugl", "host", "include")
172        self.host_vk_include_dir = \
173            envGetOrDefault("VK_CEREAL_HOST_INCLUDE_DIR",
174                            default_host_include_dir)
175
176        self.host_cmake_generator = lambda cppFiles: f"""{autogeneratedMkTemplate % banner_command(sys.argv)}
177add_library(OpenglRender_vulkan_cereal {cppFiles})
178target_compile_definitions(OpenglRender_vulkan_cereal PRIVATE -DVK_ANDROID_native_buffer -DVK_GOOGLE_gfxstream)
179if (WIN32)
180    target_compile_definitions(OpenglRender_vulkan_cereal PRIVATE -DVK_USE_PLATFORM_WIN32_KHR)
181endif()
182target_link_libraries(OpenglRender_vulkan_cereal PUBLIC {self.baseLibLinkName})
183
184target_include_directories(OpenglRender_vulkan_cereal
185                           PUBLIC
186                           .
187                           PRIVATE
188                           ..
189                           ../..
190                           ../../../include)
191"""
192
193        self.guest_android_mk_generator = lambda cppFiles: """%s
194LOCAL_PATH := $(call my-dir)
195
196$(call emugl-begin-shared-library,libvulkan_enc)
197$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
198$(call emugl-import,libOpenglCodecCommon$(GOLDFISH_OPENGL_LIB_SUFFIX) libandroidemu lib_renderControl_enc)
199
200# Vulkan include dir
201ifeq (true,$(GOLDFISH_OPENGL_BUILD_FOR_HOST))
202LOCAL_C_INCLUDES += \\
203    $(LOCAL_PATH) \\
204    $(HOST_EMUGL_PATH)/host/include \\
205    $(HOST_EMUGL_PATH)/host/include/vulkan
206endif
207
208ifneq (true,$(GOLDFISH_OPENGL_BUILD_FOR_HOST))
209LOCAL_C_INCLUDES += \\
210    $(LOCAL_PATH) \\
211    $(LOCAL_PATH)/../vulkan_enc \\
212
213LOCAL_HEADER_LIBRARIES += \\
214    hwvulkan_headers \\
215    vulkan_headers \\
216
217endif
218
219LOCAL_CFLAGS += \\
220    -DLOG_TAG=\\"goldfish_vulkan\\" \\
221    -DVK_ANDROID_native_buffer \\
222    -DVK_GOOGLE_address_space \\
223    -Wno-missing-field-initializers \\
224    -Werror \\
225    -fstrict-aliasing \\
226    -DVK_USE_PLATFORM_ANDROID_KHR \\
227    -DVK_NO_PROTOTYPES \\
228
229LOCAL_SRC_FILES := AndroidHardwareBuffer.cpp \\
230    HostVisibleMemoryVirtualization.cpp \\
231    Resources.cpp \\
232    Validation.cpp \\
233    %s.cpp \\
234    VulkanHandleMapping.cpp \\
235    ResourceTracker.cpp \\
236    %s
237
238ifeq (true,$(GOLDFISH_OPENGL_BUILD_FOR_HOST))
239LOCAL_CFLAGS += -D__ANDROID_API__=28
240$(call emugl-export,SHARED_LIBRARIES,libgui)
241else
242$(call emugl-export,SHARED_LIBRARIES,libsync libnativewindow)
243LOCAL_STATIC_LIBRARIES += libarect
244endif
245
246$(call emugl-end-module)
247"""% (autogeneratedMkTemplate % banner_command(sys.argv), VULKAN_STREAM_TYPE_GUEST, cppFiles)
248
249        encoderInclude = f"""
250#include "goldfish_vk_private_defs.h"
251#include <memory>
252class IOStream;
253"""
254        encoderImplInclude = f"""
255#include "IOStream.h"
256#include "Resources.h"
257#include "ResourceTracker.h"
258#include "Validation.h"
259#include "{VULKAN_STREAM_TYPE_GUEST}.h"
260
261#include "{self.guestBaseLibDirPrefix}/AlignedBuf.h"
262#include "{self.guestBaseLibDirPrefix}/BumpPool.h"
263#include "{self.guestBaseLibDirPrefix}/synchronization/AndroidLock.h"
264
265#include <cutils/properties.h>
266
267#include "goldfish_vk_marshaling_guest.h"
268#include "goldfish_vk_reserved_marshaling_guest.h"
269#include "goldfish_vk_deepcopy_guest.h"
270#include "goldfish_vk_counting_guest.h"
271#include "goldfish_vk_handlemap_guest.h"
272#include "goldfish_vk_private_defs.h"
273#include "goldfish_vk_transform_guest.h"
274
275#include <unordered_map>
276
277"""
278
279        functableImplInclude = """
280#include "VkEncoder.h"
281#include "../OpenglSystemCommon/HostConnection.h"
282#include "ResourceTracker.h"
283
284#include "goldfish_vk_private_defs.h"
285
286#include <log/log.h>
287#include <cstring>
288
289// Stuff we are not going to use but if included,
290// will cause compile errors. These are Android Vulkan
291// required extensions, but the approach will be to
292// implement them completely on the guest side.
293#undef VK_KHR_android_surface
294"""
295        marshalIncludeGuest = """
296#include "goldfish_vk_marshaling_guest.h"
297#include "goldfish_vk_private_defs.h"
298#include "%s.h"
299
300// Stuff we are not going to use but if included,
301// will cause compile errors. These are Android Vulkan
302// required extensions, but the approach will be to
303// implement them completely on the guest side.
304#undef VK_KHR_android_surface
305#undef VK_ANDROID_external_memory_android_hardware_buffer
306""" % VULKAN_STREAM_TYPE_GUEST
307
308        reservedmarshalIncludeGuest = """
309#include "goldfish_vk_marshaling_guest.h"
310#include "goldfish_vk_private_defs.h"
311#include "%s.h"
312
313// Stuff we are not going to use but if included,
314// will cause compile errors. These are Android Vulkan
315// required extensions, but the approach will be to
316// implement them completely on the guest side.
317#undef VK_KHR_android_surface
318#undef VK_ANDROID_external_memory_android_hardware_buffer
319""" % VULKAN_STREAM_TYPE_GUEST
320
321        reservedmarshalImplIncludeGuest = """
322#include "Resources.h"
323"""
324
325        vulkanStreamIncludeHost = f"""
326#include "goldfish_vk_private_defs.h"
327
328#include "{VULKAN_STREAM_TYPE}.h"
329#include "{self.baseLibDirPrefix}/StreamSerializing.h"
330"""
331
332        testingInclude = """
333#include "goldfish_vk_private_defs.h"
334#include <string.h>
335#include <functional>
336using OnFailCompareFunc = std::function<void(const char*)>;
337"""
338        poolInclude = f"""
339#include "goldfish_vk_private_defs.h"
340#include "{self.baseLibDirPrefix}/BumpPool.h"
341using android::base::Allocator;
342using android::base::BumpPool;
343"""
344        handleMapInclude = """
345#include "goldfish_vk_private_defs.h"
346#include "VulkanHandleMapping.h"
347"""
348        transformIncludeGuest = """
349#include "goldfish_vk_private_defs.h"
350"""
351        transformInclude = """
352#include "goldfish_vk_private_defs.h"
353#include "goldfish_vk_extension_structs.h"
354"""
355        transformImplIncludeGuest = """
356#include "ResourceTracker.h"
357"""
358        transformImplInclude = """
359#include "VkDecoderGlobalState.h"
360"""
361        deepcopyInclude = """
362#include "vk_util.h"
363"""
364        poolIncludeGuest = f"""
365#include "goldfish_vk_private_defs.h"
366#include "{self.guestBaseLibDirPrefix}/BumpPool.h"
367using android::base::Allocator;
368using android::base::BumpPool;
369// Stuff we are not going to use but if included,
370// will cause compile errors. These are Android Vulkan
371// required extensions, but the approach will be to
372// implement them completely on the guest side.
373#undef VK_KHR_android_surface
374#undef VK_ANDROID_external_memory_android_hardware_buffer
375"""
376        handleMapIncludeGuest = """
377#include "goldfish_vk_private_defs.h"
378#include "VulkanHandleMapping.h"
379// Stuff we are not going to use but if included,
380// will cause compile errors. These are Android Vulkan
381// required extensions, but the approach will be to
382// implement them completely on the guest side.
383#undef VK_KHR_android_surface
384#undef VK_ANDROID_external_memory_android_hardware_buffer
385"""
386        dispatchHeaderDefs = """
387#include "goldfish_vk_private_defs.h"
388namespace goldfish_vk {
389
390struct VulkanDispatch;
391
392} // namespace goldfish_vk
393using DlOpenFunc = void* (void);
394using DlSymFunc = void* (void*, const char*);
395"""
396
397        extensionStructsInclude = """
398#include "goldfish_vk_private_defs.h"
399"""
400
401        extensionStructsIncludeGuest = """
402#include "vk_platform_compat.h"
403#include "goldfish_vk_private_defs.h"
404// Stuff we are not going to use but if included,
405// will cause compile errors. These are Android Vulkan
406// required extensions, but the approach will be to
407// implement them completely on the guest side.
408#undef VK_KHR_android_surface
409#undef VK_ANDROID_external_memory_android_hardware_buffer
410"""
411        commonCerealImplIncludes = """
412#include "goldfish_vk_extension_structs.h"
413#include "goldfish_vk_private_defs.h"
414#include <string.h>
415"""
416        commonCerealIncludesGuest = """
417#include "vk_platform_compat.h"
418"""
419        commonCerealImplIncludesGuest = """
420#include "goldfish_vk_extension_structs_guest.h"
421#include "goldfish_vk_private_defs.h"
422
423#include <cstring>
424"""
425        countingIncludes = """
426#include "vk_platform_compat.h"
427#include "goldfish_vk_private_defs.h"
428"""
429
430        dispatchImplIncludes = """
431#include <stdio.h>
432#include <stdlib.h>
433#include <string.h>
434"""
435
436        decoderSnapshotHeaderIncludes = """
437#include <memory>
438#include "common/goldfish_vk_private_defs.h"
439"""
440        decoderSnapshotImplIncludes = f"""
441#include "VulkanHandleMapping.h"
442#include "VkDecoderGlobalState.h"
443#include "VkReconstruction.h"
444
445#include "{self.baseLibDirPrefix}/Lock.h"
446"""
447
448        decoderHeaderIncludes = """
449#include <memory>
450
451namespace android {
452namespace base {
453class BumpPool;
454} // namespace android
455} // namespace base
456
457"""
458
459        decoderImplIncludes = f"""
460#include "common/goldfish_vk_marshaling.h"
461#include "common/goldfish_vk_reserved_marshaling.h"
462#include "common/goldfish_vk_private_defs.h"
463#include "common/goldfish_vk_transform.h"
464
465#include "{self.baseLibDirPrefix}/BumpPool.h"
466#include "{self.baseLibDirPrefix}/System.h"
467#include "{self.baseLibDirPrefix}/Tracing.h"
468#include "stream-servers/IOStream.h"
469#include "host-common/feature_control.h"
470#include "host-common/GfxstreamFatalError.h"
471#include "host-common/logging.h"
472
473#include "VkDecoderGlobalState.h"
474#include "VkDecoderSnapshot.h"
475
476#include "VulkanDispatch.h"
477#include "%s.h"
478
479#include <unordered_map>
480""" % VULKAN_STREAM_TYPE
481
482        self.guest_encoder_tag = "guest_encoder"
483        self.guest_hal_tag = "guest_hal"
484        self.host_tag = "host"
485
486        self.guest_abs_encoder_destination = \
487            os.environ["VK_CEREAL_GUEST_ENCODER_DIR"]
488        self.guest_abs_hal_destination = \
489            os.environ["VK_CEREAL_GUEST_HAL_DIR"]
490        self.host_abs_decoder_destination = \
491            os.environ["VK_CEREAL_HOST_DECODER_DIR"]
492
493        self.addGuestEncoderModule(
494            "VkEncoder",
495            extraHeader = encoderInclude,
496            extraImpl = encoderImplInclude)
497
498        self.addGuestEncoderModule("goldfish_vk_extension_structs_guest",
499                                   extraHeader=extensionStructsIncludeGuest)
500        self.addGuestEncoderModule("goldfish_vk_marshaling_guest",
501                                   extraHeader=commonCerealIncludesGuest + marshalIncludeGuest,
502                                   extraImpl=commonCerealImplIncludesGuest)
503        self.addGuestEncoderModule("goldfish_vk_reserved_marshaling_guest",
504                                   extraHeader=commonCerealIncludesGuest + reservedmarshalIncludeGuest,
505                                   extraImpl=commonCerealImplIncludesGuest + reservedmarshalImplIncludeGuest)
506        self.addGuestEncoderModule("goldfish_vk_deepcopy_guest",
507                                   extraHeader=commonCerealIncludesGuest + poolIncludeGuest,
508                                   extraImpl=commonCerealImplIncludesGuest + deepcopyInclude)
509        self.addGuestEncoderModule("goldfish_vk_counting_guest",
510                                   extraHeader=countingIncludes,
511                                   extraImpl=commonCerealImplIncludesGuest)
512        self.addGuestEncoderModule("goldfish_vk_handlemap_guest",
513                                   extraHeader=commonCerealIncludesGuest + handleMapIncludeGuest,
514                                   extraImpl=commonCerealImplIncludesGuest)
515        self.addGuestEncoderModule("goldfish_vk_transform_guest",
516                                   extraHeader=commonCerealIncludesGuest + transformIncludeGuest,
517                                   extraImpl=commonCerealImplIncludesGuest + transformImplIncludeGuest)
518
519        self.addGuestEncoderModule("func_table", extraImpl=functableImplInclude)
520
521        self.addModule("common", "goldfish_vk_extension_structs",
522                       extraHeader=extensionStructsInclude)
523        self.addModule("common", "goldfish_vk_marshaling",
524                       extraHeader=vulkanStreamIncludeHost,
525                       extraImpl=commonCerealImplIncludes)
526        self.addModule("common", "goldfish_vk_reserved_marshaling",
527                       extraHeader=vulkanStreamIncludeHost,
528                       extraImpl=commonCerealImplIncludes)
529        self.addModule("common", "goldfish_vk_testing",
530                       extraHeader=testingInclude,
531                       extraImpl=commonCerealImplIncludes)
532        self.addModule("common", "goldfish_vk_deepcopy",
533                       extraHeader=poolInclude,
534                       extraImpl=commonCerealImplIncludes + deepcopyInclude)
535        self.addModule("common", "goldfish_vk_handlemap",
536                       extraHeader=handleMapInclude,
537                       extraImpl=commonCerealImplIncludes)
538        self.addModule("common", "goldfish_vk_dispatch",
539                       extraHeader=dispatchHeaderDefs,
540                       extraImpl=dispatchImplIncludes)
541        self.addModule("common", "goldfish_vk_transform",
542                       extraHeader=transformInclude,
543                       extraImpl=transformImplInclude)
544        self.addHostModule("VkDecoder",
545                           extraHeader=decoderHeaderIncludes,
546                           extraImpl=decoderImplIncludes,
547                           useNamespace=False)
548        self.addHostModule("VkDecoderSnapshot",
549                           extraHeader=decoderSnapshotHeaderIncludes,
550                           extraImpl=decoderSnapshotImplIncludes,
551                           useNamespace=False)
552        self.addHostModule("VkSubDecoder",
553                           extraHeader="",
554                           extraImpl="",
555                           useNamespace=False,
556                           implOnly=True)
557
558        self.addWrapper(cereal.VulkanEncoder, "VkEncoder")
559        self.addWrapper(cereal.VulkanExtensionStructs, "goldfish_vk_extension_structs_guest")
560        self.addWrapper(cereal.VulkanMarshaling, "goldfish_vk_marshaling_guest", variant = "guest")
561        self.addWrapper(cereal.VulkanReservedMarshaling, "goldfish_vk_reserved_marshaling_guest", variant = "guest")
562        self.addWrapper(cereal.VulkanDeepcopy, "goldfish_vk_deepcopy_guest")
563        self.addWrapper(cereal.VulkanCounting, "goldfish_vk_counting_guest")
564        self.addWrapper(cereal.VulkanHandleMap, "goldfish_vk_handlemap_guest")
565        self.addWrapper(cereal.VulkanTransform, "goldfish_vk_transform_guest")
566        self.addWrapper(cereal.VulkanFuncTable, "func_table")
567        self.addWrapper(cereal.VulkanExtensionStructs, "goldfish_vk_extension_structs")
568        self.addWrapper(cereal.VulkanMarshaling, "goldfish_vk_marshaling")
569        self.addWrapper(cereal.VulkanReservedMarshaling, "goldfish_vk_reserved_marshaling", variant = "host")
570        self.addWrapper(cereal.VulkanTesting, "goldfish_vk_testing")
571        self.addWrapper(cereal.VulkanDeepcopy, "goldfish_vk_deepcopy")
572        self.addWrapper(cereal.VulkanHandleMap, "goldfish_vk_handlemap")
573        self.addWrapper(cereal.VulkanDispatch, "goldfish_vk_dispatch")
574        self.addWrapper(cereal.VulkanTransform, "goldfish_vk_transform", resourceTrackerTypeName="VkDecoderGlobalState")
575        self.addWrapper(cereal.VulkanDecoder, "VkDecoder")
576        self.addWrapper(cereal.VulkanDecoderSnapshot, "VkDecoderSnapshot")
577        self.addWrapper(cereal.VulkanSubDecoder, "VkSubDecoder")
578
579        self.guestAndroidMkCppFiles = ""
580        self.hostCMakeCppFiles = ""
581        self.hostDecoderCMakeCppFiles = ""
582
583        def addSrcEntry(m):
584            mkSrcEntry = m.getMakefileSrcEntry()
585            cmakeSrcEntry = m.getCMakeSrcEntry()
586            if m.directory == self.guest_encoder_tag:
587                self.guestAndroidMkCppFiles += mkSrcEntry
588            elif m.directory == self.host_tag:
589                self.hostDecoderCMakeCppFiles += cmakeSrcEntry
590            elif m.directory != self.guest_hal_tag:
591                self.hostCMakeCppFiles += cmakeSrcEntry
592
593        self.forEachModule(addSrcEntry)
594
595    def addGuestEncoderModule(self, basename, extraHeader = "", extraImpl = "", useNamespace = True):
596        if not os.path.exists(self.guest_abs_encoder_destination):
597            print("Path [%s] not found (guest encoder path), skipping" % self.guest_abs_encoder_destination)
598            return
599
600        self.addModule(self.guest_encoder_tag,
601                       basename,
602                       extraHeader = extraHeader,
603                       extraImpl = extraImpl,
604                       customAbsDir = self.guest_abs_encoder_destination,
605                       useNamespace = useNamespace)
606
607    def addGuestHalModule(self, basename, extraHeader = "", extraImpl = "", useNamespace = True):
608        if not os.path.exists(self.guest_abs_hal_destination):
609            print("Path [%s] not found (guest encoder path), skipping" % self.guest_abs_encoder_destination)
610            return
611        self.addModule(self.guest_hal_tag,
612                       basename,
613                       extraHeader = extraHeader,
614                       extraImpl = extraImpl,
615                       customAbsDir = self.guest_abs_hal_destination,
616                       useNamespace = useNamespace)
617
618    def addHostModule(self, basename, extraHeader = "", extraImpl = "", useNamespace = True, implOnly = False):
619        if not os.path.exists(self.host_abs_decoder_destination):
620            print("Path [%s] not found (guest encoder path), skipping" % self.guest_abs_encoder_destination)
621            return
622        self.addModule(self.host_tag,
623                       basename,
624                       extraHeader = extraHeader,
625                       extraImpl = extraImpl,
626                       customAbsDir = self.host_abs_decoder_destination,
627                       useNamespace = useNamespace,
628                       implOnly = implOnly)
629
630    def addModule(self, directory, basename,
631                  extraHeader = "", extraImpl = "",
632                  customAbsDir = None,
633                  useNamespace = True,
634                  implOnly = False):
635        self.moduleList.append(basename)
636        self.modules[basename] = \
637            cereal.Module(directory, basename, customAbsDir = customAbsDir, implOnly = implOnly)
638        self.modules[basename].headerPreamble = copyrightHeader
639        self.modules[basename].headerPreamble += \
640                autogeneratedHeaderTemplate % \
641                (basename, "(header) generated by %s" % banner_command(sys.argv))
642
643        namespaceBegin = "namespace goldfish_vk {" if useNamespace else ""
644        namespaceEnd = "} // namespace goldfish_vk" if useNamespace else ""
645
646        self.modules[basename].headerPreamble += """
647#pragma once
648
649#include <vulkan/vulkan.h>
650
651%s
652
653%s
654
655""" % (extraHeader, namespaceBegin)
656
657        self.modules[basename].implPreamble = copyrightHeader
658        self.modules[basename].implPreamble += \
659                autogeneratedHeaderTemplate % \
660                (basename, "(impl) generated by %s" % \
661                    banner_command(sys.argv))
662        if not implOnly:
663            self.modules[basename].implPreamble += """
664#include "%s.h"
665
666%s
667
668%s
669
670""" % (basename, extraImpl, namespaceBegin)
671
672        self.modules[basename].headerPostamble = """
673%s
674""" % namespaceEnd
675        self.modules[basename].implPostamble = """
676%s
677""" % namespaceEnd
678
679    def addWrapper(self, moduleType, moduleName, **kwargs):
680        if moduleName not in self.modules:
681            return
682        self.wrappers.append( \
683            moduleType( \
684                self.modules[moduleName],
685                self.typeInfo, **kwargs))
686
687    def forEachModule(self, func):
688        for moduleName in self.moduleList:
689            func(self.modules[moduleName])
690
691    def forEachWrapper(self, func):
692        for wrapper in self.wrappers:
693            func(wrapper)
694
695## Overrides####################################################################
696
697    def beginFile(self, genOpts):
698        OutputGenerator.beginFile(self, genOpts, suppressEnabled)
699
700        if suppressEnabled:
701            def enableSuppression(m):
702                m.suppress = True;
703            self.forEachModule(enableSuppression)
704            self.modules[suppressExceptModule].suppress = False
705
706        if not suppressEnabled:
707            write(self.host_cmake_generator(self.hostCMakeCppFiles),
708                  file = self.outFile)
709
710            guestEncoderAndroidMkPath = \
711                os.path.join( \
712                    self.guest_abs_encoder_destination,
713                    "Android.mk")
714
715        self.forEachModule(lambda m: m.begin(self.genOpts.directory))
716        self.forEachWrapper(lambda w: w.onBegin())
717
718    def endFile(self):
719        OutputGenerator.endFile(self)
720
721        self.typeInfo.onEnd()
722
723        self.forEachWrapper(lambda w: w.onEnd())
724        self.forEachModule(lambda m: m.end())
725
726    def beginFeature(self, interface, emit):
727        # Start processing in superclass
728        OutputGenerator.beginFeature(self, interface, emit)
729
730        self.typeInfo.onBeginFeature(self.featureName)
731
732        self.forEachModule(lambda m: m.appendHeader("#ifdef %s\n" % self.featureName))
733        self.forEachModule(lambda m: m.appendImpl("#ifdef %s\n" % self.featureName))
734        self.forEachWrapper(lambda w: w.onBeginFeature(self.featureName))
735
736    def endFeature(self):
737        # Finish processing in superclass
738        OutputGenerator.endFeature(self)
739
740        self.typeInfo.onEndFeature()
741
742        self.forEachModule(lambda m: m.appendHeader("#endif\n"))
743        self.forEachModule(lambda m: m.appendImpl("#endif\n"))
744        self.forEachWrapper(lambda w: w.onEndFeature())
745
746    def genType(self, typeinfo, name, alias):
747        OutputGenerator.genType(self, typeinfo, name, alias)
748        self.typeInfo.onGenType(typeinfo, name, alias)
749        self.forEachWrapper(lambda w: w.onGenType(typeinfo, name, alias))
750
751    def genStruct(self, typeinfo, typeName, alias):
752        OutputGenerator.genStruct(self, typeinfo, typeName, alias)
753        self.typeInfo.onGenStruct(typeinfo, typeName, alias)
754        self.forEachWrapper(lambda w: w.onGenStruct(typeinfo, typeName, alias))
755
756    def genGroup(self, groupinfo, groupName, alias = None):
757        OutputGenerator.genGroup(self, groupinfo, groupName, alias)
758        self.typeInfo.onGenGroup(groupinfo, groupName, alias)
759        self.forEachWrapper(lambda w: w.onGenGroup(groupinfo, groupName, alias))
760
761    def genEnum(self, enuminfo, name, alias):
762        OutputGenerator.genEnum(self, enuminfo, name, alias)
763        self.typeInfo.onGenEnum(enuminfo, name, alias)
764        self.forEachWrapper(lambda w: w.onGenEnum(enuminfo, name, alias))
765
766    def genCmd(self, cmdinfo, name, alias):
767        OutputGenerator.genCmd(self, cmdinfo, name, alias)
768        self.typeInfo.onGenCmd(cmdinfo, name, alias)
769        self.forEachWrapper(lambda w: w.onGenCmd(cmdinfo, name, alias))
770