/* * Copyright (C) 2017 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. */ #ifndef TNT_FILAMENT_SWAPCHAIN_H #define TNT_FILAMENT_SWAPCHAIN_H #include #include #include namespace filament { /** * A swap chain represents an Operating System's *native* renderable surface. * * Typically it's a native window or a view. Because a SwapChain is initialized from a * native object, it is given to filament as a `void *`, which must be of the proper type * for each platform filament is running on. * * \code * SwapChain* swapChain = engine->createSwapChain(nativeWindow); * \endcode * * When Engine::create() is used without specifying a Platform, the `nativeWindow` * parameter above must be of type: * * Platform | nativeWindow type * :--------|:----------------------------: * Android | ANativeWindow* * OSX | NSView* * IOS | CAEAGLLayer* * X11 | Window * Windows | HWND * * Otherwise, the `nativeWindow` is defined by the concrete implementation of Platform. * * * Examples: * * Android * ------- * * On Android, an `ANativeWindow*` can be obtained from a Java `Surface` object using: * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * #include * // parameters * // env: JNIEnv* * // surface: jobject * ANativeWindow* win = ANativeWindow_fromSurface(env, surface); * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * \warning * Don't use reflection to access the `mNativeObject` field, it won't work. * * A `Surface` can be retrieved from a `SurfaceView` or `SurfaceHolder` easily using * `SurfaceHolder.getSurface()` and/or `SurfaceView.getHolder()`. * * \note * To use a `TextureView` as a SwapChain, it is necessary to first get its `SurfaceTexture`, * for instance using `TextureView.SurfaceTextureListener` and then create a `Surface`: * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java} * // using a TextureView.SurfaceTextureListener: * public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) { * mSurface = new Surface(surfaceTexture); * // mSurface can now be used in JNI to create an ANativeWindow. * } * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Linux * ----- * * Example using SDL: * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * SDL_SysWMinfo wmi; * SDL_VERSION(&wmi.version); * SDL_GetWindowWMInfo(sdlWindow, &wmi); * Window nativeWindow = (Window) wmi.info.x11.window; * * using namespace filament; * Engine* engine = Engine::create(); * SwapChain* swapChain = engine->createSwapChain((void*) nativeWindow); * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Windows * ------- * * Example using SDL: * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * SDL_SysWMinfo wmi; * SDL_VERSION(&wmi.version); * ASSERT_POSTCONDITION(SDL_GetWindowWMInfo(sdlWindow, &wmi), "SDL version unsupported!"); * HDC nativeWindow = (HDC) wmi.info.win.hdc; * * using namespace filament; * Engine* engine = Engine::create(); * SwapChain* swapChain = engine->createSwapChain((void*) nativeWindow); * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * OSX * --- * * On OSX, any `NSView` can be used *directly* as a `nativeWindow` with createSwapChain(). * * Example using SDL/Objective-C: * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.mm} * #include * * #include * #include * * SDL_SysWMinfo wmi; * SDL_VERSION(&wmi.version); * NSWindow* win = (NSWindow*) wmi.info.cocoa.window; * NSView* view = [win contentView]; * void* nativeWindow = view; * * using namespace filament; * Engine* engine = Engine::create(); * SwapChain* swapChain = engine->createSwapChain(nativeWindow); * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * @see Engine */ class UTILS_PUBLIC SwapChain : public FilamentAPI { public: static const uint64_t CONFIG_TRANSPARENT = backend::SWAP_CHAIN_CONFIG_TRANSPARENT; /** * This flag indicates that the swap chain may be used as a source surface * for reading back render results. This config must be set when creating * any swap chain that will be used as the source for a blit operation. * * @see * Renderer.copyFrame() */ static const uint64_t CONFIG_READABLE = backend::SWAP_CHAIN_CONFIG_READABLE; /** * Indicates that the native X11 window is an XCB window rather than an XLIB window. * This is ignored on non-Linux platforms and in builds that support only one X11 API. */ static const uint64_t CONFIG_ENABLE_XCB = backend::SWAP_CHAIN_CONFIG_ENABLE_XCB; /** * Indicates that the native window is a CVPixelBufferRef. * * This is only supported by the Metal backend. The CVPixelBuffer must be in the * kCVPixelFormatType_32BGRA format. * * It is not necessary to add an additional retain call before passing the pixel buffer to * Filament. Filament will call CVPixelBufferRetain during Engine::createSwapChain, and * CVPixelBufferRelease when the swap chain is destroyed. */ static const uint64_t CONFIG_APPLE_CVPIXELBUFFER = backend::SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER; void* getNativeWindow() const noexcept; }; } // namespace filament #endif // TNT_FILAMENT_SWAPCHAIN_H