1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program Tester Core 3 * ---------------------------------------- 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Raspberry PI platform. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "tcuRaspiPlatform.hpp" 25 #include "egluNativeDisplay.hpp" 26 #include "egluNativeWindow.hpp" 27 #include "egluGLContextFactory.hpp" 28 #include "deMemory.h" 29 30 tcu::Platform* createPlatform (void) 31 { 32 return new tcu::rpi::Platform(); 33 } 34 35 namespace tcu 36 { 37 namespace rpi 38 { 39 40 enum 41 { 42 DEFAULT_WINDOW_WIDTH = 400, 43 DEFAULT_WINDOW_HEIGHT = 300 44 }; 45 46 static const eglu::NativeDisplay::Capability DISPLAY_CAPABILITIES = eglu::NativeDisplay::CAPABILITY_GET_DISPLAY_LEGACY; 47 static const eglu::NativeWindow::Capability WINDOW_CAPABILITIES = eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_LEGACY; 48 49 class Display : public eglu::NativeDisplay 50 { 51 public: 52 Display (void) : eglu::NativeDisplay(DISPLAY_CAPABILITIES) {} 53 ~Display (void) {} 54 55 EGLNativeDisplayType getLegacyNative (void) { return EGL_DEFAULT_DISPLAY; } 56 }; 57 58 class DisplayFactory : public eglu::NativeDisplayFactory 59 { 60 public: 61 DisplayFactory (void); 62 ~DisplayFactory (void) {} 63 64 eglu::NativeDisplay* createDisplay (const EGLAttrib* attribList) const; 65 }; 66 67 class Window : public eglu::NativeWindow 68 { 69 public: 70 Window (int width, int height); 71 ~Window (void); 72 73 EGLNativeWindowType getLegacyNative (void) { return &m_nativeWindow; } 74 75 IVec2 getSize (void) const; 76 77 private: 78 DISPMANX_DISPLAY_HANDLE_T m_dispmanDisplay; 79 DISPMANX_ELEMENT_HANDLE_T m_dispmanElement; 80 EGL_DISPMANX_WINDOW_T m_nativeWindow; 81 }; 82 83 class WindowFactory : public eglu::NativeWindowFactory 84 { 85 public: 86 WindowFactory (void) : eglu::NativeWindowFactory("dispman", "Dispman Window", WINDOW_CAPABILITIES) {} 87 ~WindowFactory (void) {} 88 89 eglu::NativeWindow* createWindow (eglu::NativeDisplay* display, const eglu::WindowParams& params) const; 90 }; 91 92 // DisplayFactory 93 94 DisplayFactory::DisplayFactory (void) 95 : eglu::NativeDisplayFactory("default", "EGL_DEFAULT_DISPLAY", DISPLAY_CAPABILITIES) 96 { 97 m_nativeWindowRegistry.registerFactory(new WindowFactory()); 98 } 99 100 eglu::NativeDisplay* DisplayFactory::createDisplay (const EGLAttrib*) const 101 { 102 return new Display(); 103 } 104 105 // WindowFactory 106 107 eglu::NativeWindow* WindowFactory::createWindow (eglu::NativeDisplay*, const eglu::WindowParams& params) const 108 { 109 const int width = params.width != eglu::WindowParams::SIZE_DONT_CARE ? params.width : DEFAULT_WINDOW_WIDTH; 110 const int height = params.height != eglu::WindowParams::SIZE_DONT_CARE ? params.height : DEFAULT_WINDOW_HEIGHT; 111 112 return new Window(width, height); 113 } 114 115 // Window 116 117 Window::Window (int width, int height) 118 : eglu::NativeWindow(WINDOW_CAPABILITIES) 119 , m_dispmanDisplay (0) 120 , m_dispmanElement (0) 121 { 122 DISPMANX_UPDATE_HANDLE_T dispmanUpdate = 0; 123 124 // \todo [pyry] Error handling. 125 deMemset(&m_nativeWindow, 0, sizeof(m_nativeWindow)); 126 127 VC_RECT_T dstRect, srcRect; 128 129 dstRect.x = 0; 130 dstRect.y = 0; 131 dstRect.width = width; 132 dstRect.height = height; 133 134 srcRect.x = 0; 135 srcRect.y = 0; 136 srcRect.width = width << 16; 137 srcRect.height = height << 16; 138 139 m_dispmanDisplay = vc_dispmanx_display_open(0); 140 TCU_CHECK(m_dispmanDisplay); 141 142 dispmanUpdate = vc_dispmanx_update_start(0); 143 TCU_CHECK(dispmanUpdate); 144 145 m_dispmanElement = vc_dispmanx_element_add(dispmanUpdate, m_dispmanDisplay, 0/*layer*/, &dstRect, 0/*src*/, &srcRect, DISPMANX_PROTECTION_NONE, 0/*alpha*/, 0/*clamp*/, DISPMANX_NO_ROTATE); 146 TCU_CHECK(m_dispmanElement); 147 148 vc_dispmanx_update_submit_sync(dispmanUpdate); 149 150 m_nativeWindow.element = m_dispmanElement; 151 m_nativeWindow.width = width; 152 m_nativeWindow.height = height; 153 } 154 155 Window::~Window (void) 156 { 157 DISPMANX_UPDATE_HANDLE_T dispmanUpdate = 0; 158 dispmanUpdate = vc_dispmanx_update_start(0); 159 if (dispmanUpdate) 160 { 161 vc_dispmanx_element_remove(dispmanUpdate, m_dispmanElement); 162 vc_dispmanx_update_submit_sync(dispmanUpdate); 163 } 164 165 vc_dispmanx_display_close(m_dispmanDisplay); 166 } 167 168 IVec2 Window::getSize (void) const 169 { 170 return IVec2(m_nativeWindow.width, m_nativeWindow.height); 171 } 172 173 // Platform 174 175 Platform::Platform (void) 176 { 177 bcm_host_init(); 178 179 m_nativeDisplayFactoryRegistry.registerFactory(new DisplayFactory()); 180 m_contextFactoryRegistry.registerFactory(new eglu::GLContextFactory(m_nativeDisplayFactoryRegistry)); 181 } 182 183 Platform::~Platform (void) 184 { 185 } 186 187 } // rpi 188 } // tcu 189