| /* |
| * Copyright 2015 Google Inc. All Rights Reserved. |
| * |
| * 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. |
| */ |
| |
| #include "cobalt/renderer/backend/egl/graphics_system.h" |
| |
| #if defined(ENABLE_GLIMP_TRACING) |
| #include "base/debug/trace_event.h" |
| #endif |
| #if defined(GLES3_SUPPORTED) |
| #include "cobalt/renderer/backend/egl/texture_data_pbo.h" |
| #else |
| #include "cobalt/renderer/backend/egl/texture_data_cpu.h" |
| #endif |
| |
| #include "cobalt/renderer/backend/egl/display.h" |
| #include "cobalt/renderer/backend/egl/graphics_context.h" |
| #include "cobalt/renderer/backend/egl/texture.h" |
| #include "cobalt/renderer/backend/egl/utils.h" |
| #if defined(ENABLE_GLIMP_TRACING) |
| #include "glimp/tracing/tracing.h" |
| #endif |
| |
| namespace cobalt { |
| namespace renderer { |
| namespace backend { |
| |
| #if defined(ENABLE_GLIMP_TRACING) |
| // Hookup glimp tracing to Chromium's base trace_event tracing. |
| class GlimpToBaseTraceEventBridge : public glimp::TraceEventImpl { |
| public: |
| void BeginTrace(const char* name) OVERRIDE { |
| TRACE_EVENT_BEGIN0("glimp", name); |
| } |
| void EndTrace(const char* name) OVERRIDE { TRACE_EVENT_END0("glimp", name); } |
| }; |
| |
| GlimpToBaseTraceEventBridge s_glimp_to_base_trace_event_bridge; |
| #endif // #if defined(ENABLE_GLIMP_TRACING) |
| |
| GraphicsSystemEGL::GraphicsSystemEGL() { |
| #if defined(ENABLE_GLIMP_TRACING) |
| // If glimp tracing is enabled, hook up glimp trace calls to Chromium's |
| // base trace_event calls. |
| glimp::SetTraceEventImplementation(&s_glimp_to_base_trace_event_bridge); |
| #endif // #if defined(ENABLE_GLIMP_TRACING) |
| |
| display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
| CHECK_NE(EGL_NO_DISPLAY, display_); |
| CHECK_EQ(EGL_SUCCESS, eglGetError()); |
| EGL_CALL(eglInitialize(display_, NULL, NULL)); |
| |
| // Setup our configuration to support RGBA and compatibility with PBuffer |
| // objects (for offscreen rendering). |
| EGLint attribute_list[] = {EGL_SURFACE_TYPE, // this must be first |
| EGL_WINDOW_BIT | EGL_PBUFFER_BIT | |
| EGL_SWAP_BEHAVIOR_PRESERVED_BIT, |
| EGL_RED_SIZE, |
| 8, |
| EGL_GREEN_SIZE, |
| 8, |
| EGL_BLUE_SIZE, |
| 8, |
| EGL_ALPHA_SIZE, |
| 8, |
| #if !SB_HAS_QUIRK(NO_EGL_BIND_TO_TEXTURE) |
| EGL_BIND_TO_TEXTURE_RGBA, |
| EGL_TRUE, |
| #endif |
| EGL_RENDERABLE_TYPE, |
| EGL_OPENGL_ES2_BIT, |
| EGL_NONE}; |
| |
| // Try to allow preservation of the frame contents between swap calls -- |
| // this will allow rendering of only parts of the frame that have changed. |
| DCHECK_EQ(EGL_SURFACE_TYPE, attribute_list[0]); |
| EGLint& surface_type_value = attribute_list[1]; |
| |
| EGLint num_configs; |
| eglChooseConfig(display_, attribute_list, &config_, 1, &num_configs); |
| if (eglGetError() != EGL_SUCCESS || num_configs == 0) { |
| // Swap buffer preservation may not be supported. Try to find a config |
| // without the feature. |
| surface_type_value &= ~EGL_SWAP_BEHAVIOR_PRESERVED_BIT; |
| EGL_CALL( |
| eglChooseConfig(display_, attribute_list, &config_, 1, &num_configs)); |
| } |
| DCHECK_EQ(1, num_configs); |
| |
| #if defined(GLES3_SUPPORTED) |
| resource_context_.emplace(display_, config_); |
| #endif |
| } |
| |
| GraphicsSystemEGL::~GraphicsSystemEGL() { |
| resource_context_ = base::nullopt; |
| eglTerminate(display_); |
| } |
| |
| scoped_ptr<Display> GraphicsSystemEGL::CreateDisplay( |
| system_window::SystemWindow* system_window) { |
| EGLNativeWindowType window_handle = GetHandleFromSystemWindow(system_window); |
| return scoped_ptr<Display>(new DisplayEGL(display_, config_, window_handle)); |
| } |
| |
| scoped_ptr<GraphicsContext> GraphicsSystemEGL::CreateGraphicsContext() { |
| // If GLES3 is supported, we will make use of PBOs to allocate buffers for |
| // texture data and populate them on separate threads. In order to access |
| // that data from graphics contexts created through this method, we must |
| // enable sharing between them and the resource context, which is why we |
| // must pass it in here. |
| #if defined(GLES3_SUPPORTED) |
| ResourceContext* resource_context = &(resource_context_.value()); |
| #else |
| ResourceContext* resource_context = NULL; |
| #endif |
| return scoped_ptr<GraphicsContext>( |
| new GraphicsContextEGL(this, display_, config_, resource_context)); |
| } |
| |
| scoped_ptr<TextureDataEGL> GraphicsSystemEGL::AllocateTextureData( |
| const math::Size& size, GLenum format) { |
| #if defined(GLES3_SUPPORTED) |
| return scoped_ptr<TextureDataEGL>( |
| new TextureDataPBO(&(resource_context_.value()), size, format)); |
| #else |
| return scoped_ptr<TextureDataEGL>(new TextureDataCPU(size, format)); |
| #endif |
| } |
| |
| scoped_ptr<RawTextureMemoryEGL> GraphicsSystemEGL::AllocateRawTextureMemory( |
| size_t size_in_bytes, size_t alignment) { |
| #if defined(GLES3_SUPPORTED) |
| return scoped_ptr<RawTextureMemoryEGL>(new RawTextureMemoryPBO( |
| &(resource_context_.value()), size_in_bytes, alignment)); |
| #else |
| return scoped_ptr<RawTextureMemoryEGL>( |
| new RawTextureMemoryCPU(size_in_bytes, alignment)); |
| #endif |
| } |
| |
| } // namespace backend |
| } // namespace renderer |
| } // namespace cobalt |