1ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson/* 2ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. 3ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* 4ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* Redistribution and use in source and binary forms, with or without 5ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* modification, are permitted provided that the following conditions are 6ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* met: 7ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* * Redistributions of source code must retain the above copyright 8ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* notice, this list of conditions and the following disclaimer. 9ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* * Redistributions in binary form must reproduce the above 10ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* copyright notice, this list of conditions and the following 11ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* disclaimer in the documentation and/or other materials provided 12ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* with the distribution. 13ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* * Neither the name of The Linux Foundation. nor the names of its 14ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* contributors may be used to endorse or promote products derived 15ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* from this software without specific prior written permission. 16ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* 17ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson*/ 29ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 30ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#ifndef OVERLAY_H 31ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#define OVERLAY_H 32ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 33ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include "overlayUtils.h" 34a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include "mdp_version.h" 35ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include "utils/threads.h" 36ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 37ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstruct MetaData_t; 38ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 39ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonnamespace overlay { 40ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonclass GenericPipe; 41ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 42ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonclass Overlay : utils::NoCopy { 43ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonpublic: 44ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson enum { DMA_BLOCK_MODE, DMA_LINE_MODE }; 45ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //Abstract Display types. Each backed by a LayerMixer, 46ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //represented by a fb node. 47ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //High res panels can be backed by 2 layer mixers and a single fb node. 48ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson enum { DPY_PRIMARY, DPY_EXTERNAL, DPY_WRITEBACK, DPY_UNUSED }; 49ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson enum { DPY_MAX = DPY_UNUSED }; 50ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson enum { MIXER_LEFT, MIXER_RIGHT, MIXER_UNUSED }; 51ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson enum { MIXER_DEFAULT = MIXER_LEFT, MIXER_MAX = MIXER_UNUSED }; 52ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson enum { MAX_FB_DEVICES = DPY_MAX }; 53a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah enum { FORMAT_YUV, FORMAT_RGB }; 54a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah 55a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah struct PipeSpecs { 56a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah PipeSpecs() : formatClass(FORMAT_RGB), needsScaling(false), fb(false), 57ba33c33f54132af55509d5ffaf6d8d344368495fXu Yang dpy(DPY_PRIMARY), mixer(MIXER_DEFAULT), numActiveDisplays(1) {} 58a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah int formatClass; 59a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah bool needsScaling; 60a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah bool fb; 61a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah int dpy; 62a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah int mixer; 63ba33c33f54132af55509d5ffaf6d8d344368495fXu Yang int numActiveDisplays; 64a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah }; 65ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 66ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson /* dtor close */ 67ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ~Overlay(); 68ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 69ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson /* Marks the beginning of a drawing round, resets usage bits on pipes 70ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * Should be called when drawing begins before any pipe config is done. 71ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson */ 72ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson void configBegin(); 73ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 74ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson /* Marks the end of config for this drawing round 75ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * Will do garbage collection of pipe objects and thus calling UNSETs, 76ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * closing FDs, removing rotator objects and memory, if allocated. 77ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * Should be called after all pipe configs are done. 78ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson */ 79ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson void configDone(); 80ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 81a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah /* Get a pipe that supported the specified format class (yuv, rgb) and has 82a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah * scaling capabilities. 83a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah */ 84a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah utils::eDest getPipe(const PipeSpecs& pipeSpecs); 85a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* Returns the eDest corresponding to an already allocated pipeid. 86a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * Useful for the reservation case, when libvpu reserves the pipe at its 87a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * end, and expect the overlay to allocate a given pipe for a layer. 88a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson */ 89a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson utils::eDest reservePipe(int pipeid); 90a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* getting dest for the given pipeid */ 91a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson utils::eDest getDest(int pipeid); 92a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* getting overlay.pipeid for the given dest */ 93a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson int getPipeId(utils::eDest dest); 94ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 95ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson void setSource(const utils::PipeArgs args, utils::eDest dest); 96ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson void setCrop(const utils::Dim& d, utils::eDest dest); 97a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson void setColor(const uint32_t color, utils::eDest dest); 98ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson void setTransform(const int orientation, utils::eDest dest); 99ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson void setPosition(const utils::Dim& dim, utils::eDest dest); 100ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson void setVisualParams(const MetaData_t& data, utils::eDest dest); 101ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson bool commit(utils::eDest dest); 102ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson bool queueBuffer(int fd, uint32_t offset, utils::eDest dest); 103ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 104a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* pipe reservation session is running */ 105a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson bool sessionInProgress(utils::eDest dest); 106a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* pipe reservation session has ended*/ 107a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson bool isSessionEnded(utils::eDest dest); 108a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* start session for the pipe reservation */ 109a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson void startSession(utils::eDest dest); 110a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* end all started sesisons */ 111a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson void endAllSessions(); 112ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson /* Returns available ("unallocated") pipes for a display's mixer */ 113ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int availablePipes(int dpy, int mixer); 114a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* Returns available ("unallocated") pipes for a display */ 115a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson int availablePipes(int dpy); 116a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* Returns available ("unallocated") pipe of given type for a display */ 117a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson int availablePipes(int dpy, utils::eMdpPipeType type); 118ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson /* Returns if any of the requested pipe type is attached to any of the 119ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * displays 120ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson */ 121ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson bool isPipeTypeAttached(utils::eMdpPipeType type); 1220bc6186c13bed6530aadad53308916869871aa8cSaurabh Shah /* Compare pipe priorities and return 1230bc6186c13bed6530aadad53308916869871aa8cSaurabh Shah * 1 if 1st pipe has a higher priority 1240bc6186c13bed6530aadad53308916869871aa8cSaurabh Shah * 0 if both have the same priority 1250bc6186c13bed6530aadad53308916869871aa8cSaurabh Shah *-1 if 2nd pipe has a higher priority 1260bc6186c13bed6530aadad53308916869871aa8cSaurabh Shah */ 1270bc6186c13bed6530aadad53308916869871aa8cSaurabh Shah int comparePipePriority(utils::eDest pipe1Index, utils::eDest pipe2Index); 128ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson /* Returns pipe dump. Expects a NULL terminated buffer of big enough size 129ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * to populate. 130ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson */ 1314418482cd51e8343e7efd978ccdd17c616d1d78aRaj Kamal /* Returns if DMA pipe multiplexing is supported by the mdss driver */ 1324418482cd51e8343e7efd978ccdd17c616d1d78aRaj Kamal static bool isDMAMultiplexingSupported(); 1334418482cd51e8343e7efd978ccdd17c616d1d78aRaj Kamal /* Returns if UI scaling on external is supported on the targets */ 1344418482cd51e8343e7efd978ccdd17c616d1d78aRaj Kamal static bool isUIScalingOnExternalSupported(); 135ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson void getDump(char *buf, size_t len); 136ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson /* Reset usage and allocation bits on all pipes for given display */ 137ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson void clear(int dpy); 138a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* Validate the set of pipes for a display and set them in driver */ 139a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson bool validateAndSet(const int& dpy, const int& fbFd); 140ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 141ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson /* Closes open pipes, called during startup */ 142ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static int initOverlay(); 143ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson /* Returns the singleton instance of overlay */ 144ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static Overlay* getInstance(); 145ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static void setDMAMode(const int& mode); 146ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static int getDMAMode(); 147ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson /* Returns the framebuffer node backing up the display */ 148ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static int getFbForDpy(const int& dpy); 1496f7634666209698e4835b9f326278a7068834383Jeykumar Sankaran 150ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static bool displayCommit(const int& fd); 1516f7634666209698e4835b9f326278a7068834383Jeykumar Sankaran /* Overloads display commit with ROI's of each halves. 1526f7634666209698e4835b9f326278a7068834383Jeykumar Sankaran * Single interface panels will only update left ROI. */ 1536f7634666209698e4835b9f326278a7068834383Jeykumar Sankaran static bool displayCommit(const int& fd, const utils::Dim& lRoi, 1546f7634666209698e4835b9f326278a7068834383Jeykumar Sankaran const utils::Dim& rRoi); 155ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 156ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonprivate: 157ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson /* Ctor setup */ 158ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson explicit Overlay(); 159ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson /*Validate index range, abort if invalid */ 160ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson void validate(int index); 161a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson static void setDMAMultiplexingSupported(); 162ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson void dump() const; 163a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah /* Returns an available pipe based on the type of pipe requested. When ANY 164a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah * is requested, the first available VG or RGB is returned. If no pipe is 165a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah * available for the display "dpy" then INV is returned. Note: If a pipe is 166a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah * assigned to a certain display, then it cannot be assigned to another 167a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah * display without being garbage-collected once. To add if a pipe is 168a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah * asisgned to a mixer within a display it cannot be reused for another 169a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah * mixer without being UNSET once*/ 170a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah utils::eDest nextPipe(utils::eMdpPipeType, int dpy, int mixer); 171a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah /* Helpers that enfore target specific policies while returning pipes */ 172a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah utils::eDest getPipe_8x26(const PipeSpecs& pipeSpecs); 173a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah utils::eDest getPipe_8x16(const PipeSpecs& pipeSpecs); 1743fdd1867c6a39a4397ea74370c0d895be30b0e76Prabhanjan Kandula utils::eDest getPipe_8x39(const PipeSpecs& pipeSpecs); 175a83d776f160d90db1cb5df28a793f4f06a93f020Saurabh Shah 1763f38b62b3d70dfea36d63c814abaed4da1fcd01cSaurabh Shah /* Returns the handle to libscale.so's programScale function */ 1773f38b62b3d70dfea36d63c814abaed4da1fcd01cSaurabh Shah static int (*getFnProgramScale())(struct mdp_overlay_list *); 178a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* Creates a scalar object using libscale.so */ 179a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson static void initScalar(); 180a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* Destroys the scalar object using libscale.so */ 181a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson static void destroyScalar(); 182ab05b00fefd34a761dfaf1ccaf8ad14d325873f4radhakrishna /* Sets the pipe type RGB/VG/DMA*/ 183ab05b00fefd34a761dfaf1ccaf8ad14d325873f4radhakrishna void setPipeType(utils::eDest pipeIndex, const utils::eMdpPipeType pType); 184ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 185ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson /* Just like a Facebook for pipes, but much less profile info */ 186ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson struct PipeBook { 187ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson void init(); 188ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson void destroy(); 189ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson /* Check if pipe exists and return true, false otherwise */ 190ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson bool valid(); 191ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 192ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson /* Hardware pipe wrapper */ 193ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson GenericPipe *mPipe; 194ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson /* Display using this pipe. Refer to enums above */ 195ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int mDisplay; 196ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson /* Mixer within a split display this pipe is attached to */ 197ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int mMixer; 198ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 199ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson /* operations on bitmap */ 200ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static bool pipeUsageUnchanged(); 201ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static void setUse(int index); 202ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static void resetUse(int index); 203ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static bool isUsed(int index); 204ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static bool isNotUsed(int index); 205ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static void save(); 206ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 207ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static void setAllocation(int index); 208ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static void resetAllocation(int index); 209ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static bool isAllocated(int index); 210ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static bool isNotAllocated(int index); 211ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 212ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static utils::eMdpPipeType getPipeType(utils::eDest dest); 213ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static const char* getDestStr(utils::eDest dest); 214ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 215ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static int NUM_PIPES; 216ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static utils::eMdpPipeType pipeTypeLUT[utils::OV_MAX]; 217a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* Session for reserved pipes */ 218a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson enum Session { 219a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson NONE, 220a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson START, 221a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson END 222a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson }; 223a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson Session mSession; 224ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 225ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson private: 226ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //usage tracks if a successful commit happened. So a pipe could be 227ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //allocated to a display, but it may not end up using it for various 228ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //reasons. If one display actually uses a pipe then it amy not be 229ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //used by another display, without an UNSET in between. 230ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static int sPipeUsageBitmap; 231ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static int sLastUsageBitmap; 232ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //Tracks which pipe objects are allocated. This does not imply that they 233ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //will actually be used. For example, a display might choose to acquire 234ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //3 pipe objects in one shot and proceed with config only if it gets all 235ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //3. The bitmap helps allocate different pipe objects on each request. 236ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static int sAllocatedBitmap; 237ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson }; 238ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 239ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson PipeBook mPipeBook[utils::OV_INVALID]; //Used as max 240ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 241ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson /* Dump string */ 242ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson char mDumpStr[1024]; 243ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 244ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson /* Singleton Instance*/ 245ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static Overlay *sInstance; 246ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static int sDpyFbMap[DPY_MAX]; 247ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static int sDMAMode; 248a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson static bool sDMAMultiplexingSupported; 249a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson static void *sLibScaleHandle; 2503f38b62b3d70dfea36d63c814abaed4da1fcd01cSaurabh Shah static int (*sFnProgramScale)(struct mdp_overlay_list *); 251a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 252a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson friend class MdpCtrl; 253ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}; 254ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 255ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsoninline void Overlay::validate(int index) { 256ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson OVASSERT(index >=0 && index < PipeBook::NUM_PIPES, \ 257ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson "%s, Index out of bounds: %d", __FUNCTION__, index); 258ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson OVASSERT(mPipeBook[index].valid(), "Pipe does not exist %s", 259ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson PipeBook::getDestStr((utils::eDest)index)); 260ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 261ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 262ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsoninline int Overlay::availablePipes(int dpy, int mixer) { 263ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int avail = 0; 264ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson for(int i = 0; i < PipeBook::NUM_PIPES; i++) { 265ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if( (mPipeBook[i].mDisplay == DPY_UNUSED || 266ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson mPipeBook[i].mDisplay == dpy) && 267ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson (mPipeBook[i].mMixer == MIXER_UNUSED || 268ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson mPipeBook[i].mMixer == mixer) && 269ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson PipeBook::isNotAllocated(i) && 270ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson !(Overlay::getDMAMode() == Overlay::DMA_BLOCK_MODE && 271ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson PipeBook::getPipeType((utils::eDest)i) == 272ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson utils::OV_MDP_PIPE_DMA)) { 273ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson avail++; 274ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 275ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 276ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return avail; 277ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 278ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 279a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsoninline int Overlay::availablePipes(int dpy) { 280a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson int avail = 0; 281a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson for(int i = 0; i < PipeBook::NUM_PIPES; i++) { 282a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if( (mPipeBook[i].mDisplay == DPY_UNUSED || 283a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson mPipeBook[i].mDisplay == dpy) && 284a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson PipeBook::isNotAllocated(i) && 285a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson !(Overlay::getDMAMode() == Overlay::DMA_BLOCK_MODE && 286a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson PipeBook::getPipeType((utils::eDest)i) == 287a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson utils::OV_MDP_PIPE_DMA)) { 288a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson avail++; 289a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 290a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 291a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return avail; 292a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson} 293a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 294a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsoninline int Overlay::availablePipes(int dpy, utils::eMdpPipeType type) { 295a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson int avail = 0; 296a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson for(int i = 0; i < PipeBook::NUM_PIPES; i++) { 297a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if((mPipeBook[i].mDisplay == DPY_UNUSED || 298a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson mPipeBook[i].mDisplay == dpy) && 299a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson PipeBook::isNotAllocated(i) && 300a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson type == PipeBook::getPipeType((utils::eDest)i)) { 301a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson avail++; 302a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 303a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 304a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return avail; 305a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson} 306a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 307ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsoninline void Overlay::setDMAMode(const int& mode) { 308ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(mode == DMA_LINE_MODE || mode == DMA_BLOCK_MODE) 309ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson sDMAMode = mode; 310ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 311ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 312a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsoninline void Overlay::setDMAMultiplexingSupported() { 313a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson sDMAMultiplexingSupported = false; 314a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(qdutils::MDPVersion::getInstance().is8x26()) 315a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson sDMAMultiplexingSupported = true; 316a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson} 317a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 3184418482cd51e8343e7efd978ccdd17c616d1d78aRaj Kamalinline bool Overlay::isDMAMultiplexingSupported() { 3194418482cd51e8343e7efd978ccdd17c616d1d78aRaj Kamal return sDMAMultiplexingSupported; 3204418482cd51e8343e7efd978ccdd17c616d1d78aRaj Kamal} 3214418482cd51e8343e7efd978ccdd17c616d1d78aRaj Kamal 3224418482cd51e8343e7efd978ccdd17c616d1d78aRaj Kamalinline bool Overlay::isUIScalingOnExternalSupported() { 3234418482cd51e8343e7efd978ccdd17c616d1d78aRaj Kamal if(qdutils::MDPVersion::getInstance().is8x26() or 3243fdd1867c6a39a4397ea74370c0d895be30b0e76Prabhanjan Kandula qdutils::MDPVersion::getInstance().is8x16() or 3253fdd1867c6a39a4397ea74370c0d895be30b0e76Prabhanjan Kandula qdutils::MDPVersion::getInstance().is8x39()) { 3264418482cd51e8343e7efd978ccdd17c616d1d78aRaj Kamal return false; 3274418482cd51e8343e7efd978ccdd17c616d1d78aRaj Kamal } 3284418482cd51e8343e7efd978ccdd17c616d1d78aRaj Kamal return true; 3294418482cd51e8343e7efd978ccdd17c616d1d78aRaj Kamal} 3304418482cd51e8343e7efd978ccdd17c616d1d78aRaj Kamal 331ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsoninline int Overlay::getDMAMode() { 332ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return sDMAMode; 333ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 334ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 335ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsoninline int Overlay::getFbForDpy(const int& dpy) { 336ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson OVASSERT(dpy >= 0 && dpy < DPY_MAX, "Invalid dpy %d", dpy); 337ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return sDpyFbMap[dpy]; 338ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 339ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 3403f38b62b3d70dfea36d63c814abaed4da1fcd01cSaurabh Shahinline int (*Overlay::getFnProgramScale())(struct mdp_overlay_list *) { 3413f38b62b3d70dfea36d63c814abaed4da1fcd01cSaurabh Shah return sFnProgramScale; 342ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 343ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 344ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsoninline bool Overlay::PipeBook::valid() { 345ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return (mPipe != NULL); 346ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 347ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 348ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsoninline bool Overlay::PipeBook::pipeUsageUnchanged() { 349ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return (sPipeUsageBitmap == sLastUsageBitmap); 350ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 351ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 352ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsoninline void Overlay::PipeBook::setUse(int index) { 353ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson sPipeUsageBitmap |= (1 << index); 354ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 355ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 356ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsoninline void Overlay::PipeBook::resetUse(int index) { 357ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson sPipeUsageBitmap &= ~(1 << index); 358ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 359ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 360ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsoninline bool Overlay::PipeBook::isUsed(int index) { 361ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return sPipeUsageBitmap & (1 << index); 362ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 363ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 364ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsoninline bool Overlay::PipeBook::isNotUsed(int index) { 365ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return !isUsed(index); 366ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 367ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 368ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsoninline void Overlay::PipeBook::save() { 369ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson sLastUsageBitmap = sPipeUsageBitmap; 370ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 371ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 372ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsoninline void Overlay::PipeBook::setAllocation(int index) { 373ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson sAllocatedBitmap |= (1 << index); 374ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 375ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 376ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsoninline void Overlay::PipeBook::resetAllocation(int index) { 377ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson sAllocatedBitmap &= ~(1 << index); 378ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 379ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 380ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsoninline bool Overlay::PipeBook::isAllocated(int index) { 381ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return sAllocatedBitmap & (1 << index); 382ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 383ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 384ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsoninline bool Overlay::PipeBook::isNotAllocated(int index) { 385ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return !isAllocated(index); 386ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 387ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 388ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsoninline utils::eMdpPipeType Overlay::PipeBook::getPipeType(utils::eDest dest) { 389ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return pipeTypeLUT[(int)dest]; 390ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 391ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 392a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsoninline void Overlay::startSession(utils::eDest dest) { 393a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson mPipeBook[(int)dest].mSession = PipeBook::START; 394a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson} 395a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 396a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsoninline bool Overlay::sessionInProgress(utils::eDest dest) { 397a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return (mPipeBook[(int)dest].mSession == PipeBook::START); 398a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson} 399a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 400a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsoninline bool Overlay::isSessionEnded(utils::eDest dest) { 401a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return (mPipeBook[(int)dest].mSession == PipeBook::END); 402a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson} 403a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 404ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsoninline const char* Overlay::PipeBook::getDestStr(utils::eDest dest) { 405ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson switch(getPipeType(dest)) { 406ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case utils::OV_MDP_PIPE_RGB: return "RGB"; 407ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case utils::OV_MDP_PIPE_VG: return "VG"; 408ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case utils::OV_MDP_PIPE_DMA: return "DMA"; 409ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson default: return "Invalid"; 410ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 411ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return "Invalid"; 412ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 413ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 414ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}; // overlay 415ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 416ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#endif // OVERLAY_H 417