1 /*
2 * Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *     * Redistributions of source code must retain the above copyright
8 *       notice, this list of conditions and the following disclaimer.
9 *     * Redistributions in binary form must reproduce the above
10 *       copyright notice, this list of conditions and the following
11 *       disclaimer in the documentation and/or other materials provided
12 *       with the distribution.
13 *     * Neither the name of The Linux Foundation nor the names of its
14 *       contributors may be used to endorse or promote products derived
15 *       from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 
30 #include <utils/locker.h>
31 #include <utils/constants.h>
32 #include <utils/debug.h>
33 #include <core/buffer_sync_handler.h>
34 
35 #include "core_impl.h"
36 
37 #define __CLASS__ "CoreInterface"
38 
39 #define GET_REVISION(version) (version >> 16)
40 #define GET_DATA_ALIGNMENT(version) ((version >> 8) & 0xFF)
41 #define GET_INSTRUCTION_SET(version) (version & 0xFF)
42 
43 namespace sdm {
44 
45 // Currently, we support only one client and one session for display core. So, create a global
46 // singleton core object.
47 struct CoreSingleton {
CoreSingletonsdm::CoreSingleton48   CoreSingleton() : core_impl(NULL) { }
49 
50   CoreImpl *core_impl;
51   Locker locker;
52 } g_core;
53 
54 // TODO(user): Have a single structure handle carries all the interface pointers.
CreateCore(DebugHandler * debug_handler,BufferAllocator * buffer_allocator,BufferSyncHandler * buffer_sync_handler,CoreInterface ** interface,uint32_t client_version)55 DisplayError CoreInterface::CreateCore(DebugHandler *debug_handler,
56                                        BufferAllocator *buffer_allocator,
57                                        BufferSyncHandler *buffer_sync_handler,
58                                        CoreInterface **interface, uint32_t client_version) {
59   SCOPE_LOCK(g_core.locker);
60 
61   if (!debug_handler || !buffer_allocator || !buffer_sync_handler || !interface) {
62     return kErrorParameters;
63   }
64 
65   // Check compatibility of client and core.
66   uint32_t lib_version = SDM_VERSION_TAG;
67   if (GET_REVISION(client_version) > GET_REVISION(lib_version)) {
68     return kErrorVersion;
69   } else if (GET_DATA_ALIGNMENT(client_version) != GET_DATA_ALIGNMENT(lib_version)) {
70     return kErrorDataAlignment;
71   } else if (GET_INSTRUCTION_SET(client_version) != GET_INSTRUCTION_SET(lib_version)) {
72     return kErrorInstructionSet;
73   }
74 
75   CoreImpl *&core_impl = g_core.core_impl;
76   if (core_impl) {
77     return kErrorUndefined;
78   }
79 
80   Debug::SetDebugHandler(debug_handler);
81 
82   // Create appropriate CoreImpl object based on client version.
83   if (GET_REVISION(client_version) == CoreImpl::kRevision) {
84     core_impl = new CoreImpl(buffer_allocator, buffer_sync_handler);
85   } else {
86     return kErrorNotSupported;
87   }
88 
89   if (!core_impl) {
90     return kErrorMemory;
91   }
92 
93   DisplayError error = core_impl->Init();
94   if (error != kErrorNone) {
95     delete core_impl;
96     core_impl = NULL;
97     return error;
98   }
99 
100   *interface = core_impl;
101   DLOGI("Open interface handle = %p", *interface);
102 
103   return kErrorNone;
104 }
105 
DestroyCore()106 DisplayError CoreInterface::DestroyCore() {
107   SCOPE_LOCK(g_core.locker);
108 
109   DLOGI("Close handle");
110 
111   CoreImpl *&core_impl = g_core.core_impl;
112   if (!core_impl) {
113     return kErrorUndefined;
114   }
115 
116   core_impl->Deinit();
117   delete core_impl;
118   core_impl = NULL;
119 
120   return kErrorNone;
121 }
122 
123 }  // namespace sdm
124 
125