/*------------------------------------------------------------------------- * 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 ¶ms) 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 ¶ms) 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) { } } // namespace rpi } // namespace tcu