/*------------------------------------------------------------------------- * drawElements Quality Program Tester Core * ---------------------------------------- * * Copyright 2014 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. * *//*! * \file * \brief Raspberry PI platform. *//*--------------------------------------------------------------------*/ #include "tcuRaspiPlatform.hpp" #include "egluNativeDisplay.hpp" #include "egluNativeWindow.hpp" #include "egluGLContextFactory.hpp" #include "deMemory.h" tcu::Platform* createPlatform (void) { return new tcu::rpi::Platform(); } namespace tcu { namespace rpi { enum { DEFAULT_WINDOW_WIDTH = 400, DEFAULT_WINDOW_HEIGHT = 300 }; static const eglu::NativeDisplay::Capability DISPLAY_CAPABILITIES = eglu::NativeDisplay::CAPABILITY_GET_DISPLAY_LEGACY; static const eglu::NativeWindow::Capability WINDOW_CAPABILITIES = eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_LEGACY; class Display : public eglu::NativeDisplay { public: Display (void) : eglu::NativeDisplay(DISPLAY_CAPABILITIES) {} ~Display (void) {} EGLNativeDisplayType getLegacyNative (void) { return EGL_DEFAULT_DISPLAY; } }; class DisplayFactory : public eglu::NativeDisplayFactory { public: DisplayFactory (void); ~DisplayFactory (void) {} eglu::NativeDisplay* createDisplay (const EGLAttrib* attribList) const; }; class Window : public eglu::NativeWindow { public: Window (int width, int height); ~Window (void); EGLNativeWindowType getLegacyNative (void) { return &m_nativeWindow; } IVec2 getSize (void) const; private: DISPMANX_DISPLAY_HANDLE_T m_dispmanDisplay; DISPMANX_ELEMENT_HANDLE_T m_dispmanElement; EGL_DISPMANX_WINDOW_T m_nativeWindow; }; class WindowFactory : public eglu::NativeWindowFactory { public: WindowFactory (void) : eglu::NativeWindowFactory("dispman", "Dispman Window", WINDOW_CAPABILITIES) {} ~WindowFactory (void) {} eglu::NativeWindow* createWindow (eglu::NativeDisplay* display, const eglu::WindowParams& params) const; }; // DisplayFactory DisplayFactory::DisplayFactory (void) : eglu::NativeDisplayFactory("default", "EGL_DEFAULT_DISPLAY", DISPLAY_CAPABILITIES) { m_nativeWindowRegistry.registerFactory(new WindowFactory()); } eglu::NativeDisplay* DisplayFactory::createDisplay (const EGLAttrib*) const { return new Display(); } // WindowFactory eglu::NativeWindow* WindowFactory::createWindow (eglu::NativeDisplay*, const eglu::WindowParams& params) const { const int width = params.width != eglu::WindowParams::SIZE_DONT_CARE ? params.width : DEFAULT_WINDOW_WIDTH; const int height = params.height != eglu::WindowParams::SIZE_DONT_CARE ? params.height : DEFAULT_WINDOW_HEIGHT; return new Window(width, height); } // Window Window::Window (int width, int height) : eglu::NativeWindow(WINDOW_CAPABILITIES) , m_dispmanDisplay (0) , m_dispmanElement (0) { DISPMANX_UPDATE_HANDLE_T dispmanUpdate = 0; // \todo [pyry] Error handling. deMemset(&m_nativeWindow, 0, sizeof(m_nativeWindow)); VC_RECT_T dstRect, srcRect; dstRect.x = 0; dstRect.y = 0; dstRect.width = width; dstRect.height = height; srcRect.x = 0; srcRect.y = 0; srcRect.width = width << 16; srcRect.height = height << 16; m_dispmanDisplay = vc_dispmanx_display_open(0); TCU_CHECK(m_dispmanDisplay); dispmanUpdate = vc_dispmanx_update_start(0); TCU_CHECK(dispmanUpdate); 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); TCU_CHECK(m_dispmanElement); vc_dispmanx_update_submit_sync(dispmanUpdate); m_nativeWindow.element = m_dispmanElement; m_nativeWindow.width = width; m_nativeWindow.height = height; } Window::~Window (void) { DISPMANX_UPDATE_HANDLE_T dispmanUpdate = 0; dispmanUpdate = vc_dispmanx_update_start(0); if (dispmanUpdate) { vc_dispmanx_element_remove(dispmanUpdate, m_dispmanElement); vc_dispmanx_update_submit_sync(dispmanUpdate); } vc_dispmanx_display_close(m_dispmanDisplay); } IVec2 Window::getSize (void) const { return IVec2(m_nativeWindow.width, m_nativeWindow.height); } // Platform Platform::Platform (void) { bcm_host_init(); m_nativeDisplayFactoryRegistry.registerFactory(new DisplayFactory()); m_contextFactoryRegistry.registerFactory(new eglu::GLContextFactory(m_nativeDisplayFactoryRegistry)); } Platform::~Platform (void) { } } // rpi } // tcu