| OLD | NEW | 
|     1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |     1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|     2 // Use of this source code is governed by a BSD-style license that can be |     2 // Use of this source code is governed by a BSD-style license that can be | 
|     3 // found in the LICENSE file. |     3 // found in the LICENSE file. | 
|     4  |     4  | 
|     5 #include "content/browser/renderer_host/compositing_iosurface_mac.h" |     5 #include "content/browser/renderer_host/compositing_iosurface_mac.h" | 
|     6  |     6  | 
|     7 #include <OpenGL/CGLRenderers.h> |     7 #include <OpenGL/CGLRenderers.h> | 
|     8 #include <OpenGL/OpenGL.h> |     8 #include <OpenGL/OpenGL.h> | 
|     9  |     9  | 
|    10 #include "base/bind.h" |    10 #include "base/bind.h" | 
|    11 #include "base/bind_helpers.h" |    11 #include "base/bind_helpers.h" | 
|    12 #include "base/command_line.h" |    12 #include "base/command_line.h" | 
|    13 #include "base/debug/trace_event.h" |    13 #include "base/debug/trace_event.h" | 
|    14 #include "base/logging.h" |    14 #include "base/logging.h" | 
|    15 #include "base/mac/mac_util.h" |    15 #include "base/mac/mac_util.h" | 
|    16 #include "base/message_loop.h" |    16 #include "base/message_loop.h" | 
|    17 #include "base/threading/platform_thread.h" |    17 #include "base/threading/platform_thread.h" | 
|    18 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h" |    18 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h" | 
|    19 #include "content/browser/renderer_host/compositing_iosurface_shader_programs_ma
      c.h" |    19 #include "content/browser/renderer_host/compositing_iosurface_shader_programs_ma
      c.h" | 
|    20 #include "content/browser/renderer_host/compositing_iosurface_transformer_mac.h" |    20 #include "content/browser/renderer_host/compositing_iosurface_transformer_mac.h" | 
|    21 #include "content/browser/renderer_host/render_widget_host_impl.h" |    21 #include "content/browser/renderer_host/render_widget_host_impl.h" | 
 |    22 #include "content/browser/renderer_host/render_widget_host_view_mac.h" | 
|    22 #include "content/common/content_constants_internal.h" |    23 #include "content/common/content_constants_internal.h" | 
|    23 #include "content/port/browser/render_widget_host_view_frame_subscriber.h" |    24 #include "content/port/browser/render_widget_host_view_frame_subscriber.h" | 
|    24 #include "gpu/command_buffer/service/gpu_switches.h" |    25 #include "gpu/command_buffer/service/gpu_switches.h" | 
|    25 #include "media/base/video_util.h" |    26 #include "media/base/video_util.h" | 
|    26 #include "third_party/skia/include/core/SkBitmap.h" |    27 #include "third_party/skia/include/core/SkBitmap.h" | 
|    27 #include "ui/gfx/rect.h" |    28 #include "ui/gfx/rect.h" | 
|    28 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" |    29 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" | 
|    29 #include "ui/gl/gl_context.h" |    30 #include "ui/gl/gl_context.h" | 
|    30 #include "ui/gfx/size_conversions.h" |    31 #include "ui/gfx/size_conversions.h" | 
|    31 #include "ui/surface/io_surface_support_mac.h" |    32 #include "ui/surface/io_surface_support_mac.h" | 
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   232     if (!pixel_buffers[i]) { |   233     if (!pixel_buffers[i]) { | 
|   233       glGenBuffersARB(1, &pixel_buffers[i]); CHECK_GL_ERROR(); |   234       glGenBuffersARB(1, &pixel_buffers[i]); CHECK_GL_ERROR(); | 
|   234     } |   235     } | 
|   235   } |   236   } | 
|   236 } |   237 } | 
|   237  |   238  | 
|   238  |   239  | 
|   239 // static |   240 // static | 
|   240 CompositingIOSurfaceMac* CompositingIOSurfaceMac::Create(int window_number) { |   241 CompositingIOSurfaceMac* CompositingIOSurfaceMac::Create(int window_number) { | 
|   241   TRACE_EVENT0("browser", "CompositingIOSurfaceMac::Create"); |   242   TRACE_EVENT0("browser", "CompositingIOSurfaceMac::Create"); | 
 |   243  | 
 |   244   scoped_refptr<CompositingIOSurfaceContext> context = | 
 |   245       CompositingIOSurfaceContext::Get(window_number); | 
 |   246   if (!context) { | 
 |   247     LOG(WARNING) << "Failed to create context for IOSurface"; | 
 |   248     return NULL; | 
 |   249   } | 
 |   250  | 
 |   251   return Create(context); | 
 |   252 } | 
 |   253  | 
 |   254 CompositingIOSurfaceMac* CompositingIOSurfaceMac::Create( | 
 |   255     const scoped_refptr<CompositingIOSurfaceContext>& context) { | 
|   242   IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); |   256   IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); | 
|   243   if (!io_surface_support) { |   257   if (!io_surface_support) { | 
|   244     LOG(WARNING) << "No IOSurface support"; |   258     LOG(WARNING) << "No IOSurface support"; | 
|   245     return NULL; |   259     return NULL; | 
|   246   } |   260   } | 
|   247  |   261  | 
|   248   scoped_refptr<CompositingIOSurfaceContext> context = |  | 
|   249       CompositingIOSurfaceContext::Get(window_number); |  | 
|   250  |  | 
|   251   return new CompositingIOSurfaceMac(io_surface_support, |   262   return new CompositingIOSurfaceMac(io_surface_support, | 
|   252                                      context); |   263                                      context); | 
|   253 } |   264 } | 
|   254  |   265  | 
|   255 CompositingIOSurfaceMac::CompositingIOSurfaceMac( |   266 CompositingIOSurfaceMac::CompositingIOSurfaceMac( | 
|   256     IOSurfaceSupport* io_surface_support, |   267     IOSurfaceSupport* io_surface_support, | 
|   257     scoped_refptr<CompositingIOSurfaceContext> context) |   268     const scoped_refptr<CompositingIOSurfaceContext>& context) | 
|   258     : io_surface_support_(io_surface_support), |   269     : io_surface_support_(io_surface_support), | 
|   259       context_(context), |   270       context_(context), | 
|   260       io_surface_handle_(0), |   271       io_surface_handle_(0), | 
 |   272       scale_factor_(1.f), | 
|   261       texture_(0), |   273       texture_(0), | 
|   262       finish_copy_timer_( |   274       finish_copy_timer_( | 
|   263           FROM_HERE, |   275           FROM_HERE, | 
|   264           base::TimeDelta::FromMilliseconds(kFinishCopyPollingPeriodMs), |   276           base::TimeDelta::FromMilliseconds(kFinishCopyPollingPeriodMs), | 
|   265           base::Bind(&CompositingIOSurfaceMac::FinishAllCopies, |   277           base::Bind(&CompositingIOSurfaceMac::FinishAllCopies, | 
|   266                      base::Unretained(this)), |   278                      base::Unretained(this)), | 
|   267           true), |   279           true), | 
|   268       display_link_(0), |   280       display_link_(0), | 
|   269       display_link_stop_timer_(FROM_HERE, base::TimeDelta::FromSeconds(1), |   281       display_link_stop_timer_(FROM_HERE, base::TimeDelta::FromSeconds(1), | 
|   270                                this, &CompositingIOSurfaceMac::StopDisplayLink), |   282                                this, &CompositingIOSurfaceMac::StopDisplayLink), | 
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   366   CGLSetCurrentContext(0); |   378   CGLSetCurrentContext(0); | 
|   367   context_ = nil; |   379   context_ = nil; | 
|   368 } |   380 } | 
|   369  |   381  | 
|   370 void CompositingIOSurfaceMac::SetIOSurface( |   382 void CompositingIOSurfaceMac::SetIOSurface( | 
|   371     uint64 io_surface_handle, |   383     uint64 io_surface_handle, | 
|   372     const gfx::Size& size, |   384     const gfx::Size& size, | 
|   373     float scale_factor, |   385     float scale_factor, | 
|   374     const ui::LatencyInfo& latency_info) { |   386     const ui::LatencyInfo& latency_info) { | 
|   375   pixel_io_surface_size_ = size; |   387   pixel_io_surface_size_ = size; | 
 |   388   scale_factor_ = scale_factor; | 
|   376   dip_io_surface_size_ = gfx::ToFlooredSize( |   389   dip_io_surface_size_ = gfx::ToFlooredSize( | 
|   377       gfx::ScaleSize(pixel_io_surface_size_, 1.0 / scale_factor)); |   390       gfx::ScaleSize(pixel_io_surface_size_, 1.0 / scale_factor_)); | 
|   378   CGLSetCurrentContext(context_->cgl_context()); |   391   CGLSetCurrentContext(context_->cgl_context()); | 
|   379   MapIOSurfaceToTexture(io_surface_handle); |   392   MapIOSurfaceToTexture(io_surface_handle); | 
|   380   CGLSetCurrentContext(0); |   393   CGLSetCurrentContext(0); | 
|   381   latency_info_.MergeWith(latency_info); |   394   latency_info_.MergeWith(latency_info); | 
|   382 } |   395 } | 
|   383  |   396  | 
|   384 int CompositingIOSurfaceMac::GetRendererID() { |   397 int CompositingIOSurfaceMac::GetRendererID() { | 
|   385   GLint current_renderer_id = -1; |   398   GLint current_renderer_id = -1; | 
|   386   if (CGLGetParameter(context_->cgl_context(), |   399   if (CGLGetParameter(context_->cgl_context(), | 
|   387                       kCGLCPCurrentRendererID, |   400                       kCGLCPCurrentRendererID, | 
|   388                       ¤t_renderer_id) == kCGLNoError) |   401                       ¤t_renderer_id) == kCGLNoError) | 
|   389     return current_renderer_id & kCGLRendererIDMatchingMask; |   402     return current_renderer_id & kCGLRendererIDMatchingMask; | 
|   390   return -1; |   403   return -1; | 
|   391 } |   404 } | 
|   392  |   405  | 
|   393 void CompositingIOSurfaceMac::DrawIOSurface( |   406 void CompositingIOSurfaceMac::DrawIOSurface( | 
|   394     NSView* view, |   407     RenderWidgetHostViewMac* render_widget_host_view) { | 
|   395     float scale_factor, |   408   DCHECK(!render_widget_host_view->use_core_animation_); | 
|   396     int window_number, |  | 
|   397     SurfaceOrder surface_order, |  | 
|   398     RenderWidgetHostViewFrameSubscriber* frame_subscriber) { |  | 
|   399  |   409  | 
 |   410   NSView* view = render_widget_host_view->cocoa_view(); | 
 |   411   content::CompositingIOSurfaceMac::SurfaceOrder surface_order = | 
 |   412      render_widget_host_view->allow_overlapping_views_ | 
 |   413      ? content::CompositingIOSurfaceMac::SURFACE_ORDER_BELOW_WINDOW | 
 |   414      : content::CompositingIOSurfaceMac::SURFACE_ORDER_ABOVE_WINDOW; | 
 |   415  | 
 |   416   SwitchToContextOnNewWindow(view, render_widget_host_view->window_number()); | 
 |   417   SetSurfaceOrder(context_->nsgl_context(), surface_order); | 
 |   418  | 
 |   419   CGLSetCurrentContext(context_->cgl_context()); | 
 |   420   [context_->nsgl_context() setView:view]; | 
 |   421  | 
 |   422   gfx::Size window_size(NSSizeToCGSize([view frame].size)); | 
 |   423  | 
 |   424   DrawIOSurface( | 
 |   425       window_size, | 
 |   426       render_widget_host_view->scale_factor(), | 
 |   427       render_widget_host_view->frame_subscriber(), | 
 |   428       false); | 
 |   429 } | 
 |   430  | 
 |   431 void CompositingIOSurfaceMac::DrawIOSurface( | 
 |   432     const gfx::Size& window_size, | 
 |   433     float window_scale_factor, | 
 |   434     RenderWidgetHostViewFrameSubscriber* frame_subscriber, | 
 |   435     bool using_core_animation) { | 
|   400   if (display_link_ == NULL) |   436   if (display_link_ == NULL) | 
|   401     SetupCVDisplayLink(); |   437     SetupCVDisplayLink(); | 
|   402  |   438  | 
|   403   SwitchToContextOnNewWindow(view, window_number); |  | 
|   404   SetSurfaceOrder(context_->nsgl_context(), surface_order); |  | 
|   405  |  | 
|   406   CGLSetCurrentContext(context_->cgl_context()); |  | 
|   407  |  | 
|   408   bool has_io_surface = MapIOSurfaceToTexture(io_surface_handle_); |   439   bool has_io_surface = MapIOSurfaceToTexture(io_surface_handle_); | 
|   409  |  | 
|   410   TRACE_EVENT1("browser", "CompositingIOSurfaceMac::DrawIOSurface", |   440   TRACE_EVENT1("browser", "CompositingIOSurfaceMac::DrawIOSurface", | 
|   411                "has_io_surface", has_io_surface); |   441                "has_io_surface", has_io_surface); | 
|   412  |   442  | 
|   413   [context_->nsgl_context() setView:view]; |  | 
|   414   gfx::Size window_size(NSSizeToCGSize([view frame].size)); |  | 
|   415   gfx::Size pixel_window_size = gfx::ToFlooredSize( |   443   gfx::Size pixel_window_size = gfx::ToFlooredSize( | 
|   416       gfx::ScaleSize(window_size, scale_factor)); |   444       gfx::ScaleSize(window_size, window_scale_factor)); | 
|   417   glViewport(0, 0, pixel_window_size.width(), pixel_window_size.height()); |   445   glViewport(0, 0, pixel_window_size.width(), pixel_window_size.height()); | 
|   418  |   446  | 
|   419   SurfaceQuad quad; |   447   SurfaceQuad quad; | 
|   420   quad.set_size(dip_io_surface_size_, pixel_io_surface_size_); |   448   quad.set_size(dip_io_surface_size_, pixel_io_surface_size_); | 
|   421  |   449  | 
|   422   glMatrixMode(GL_PROJECTION); |   450   glMatrixMode(GL_PROJECTION); | 
|   423   glLoadIdentity(); |   451   glLoadIdentity(); | 
|   424  |   452  | 
|   425   // Note that the projection keeps things in view units, so the use of |   453   // Note that the projection keeps things in view units, so the use of | 
|   426   // window_size / dip_io_surface_size_ (as opposed to the pixel_ variants) |   454   // window_size / dip_io_surface_size_ (as opposed to the pixel_ variants) | 
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   506     const base::Time present_time = base::Time::Now(); |   534     const base::Time present_time = base::Time::Now(); | 
|   507     scoped_refptr<media::VideoFrame> frame; |   535     scoped_refptr<media::VideoFrame> frame; | 
|   508     RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback; |   536     RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback; | 
|   509     if (frame_subscriber->ShouldCaptureFrame(present_time, &frame, &callback)) { |   537     if (frame_subscriber->ShouldCaptureFrame(present_time, &frame, &callback)) { | 
|   510       copy_done_callback = CopyToVideoFrameWithinContext( |   538       copy_done_callback = CopyToVideoFrameWithinContext( | 
|   511           gfx::Rect(pixel_io_surface_size_), true, frame, |   539           gfx::Rect(pixel_io_surface_size_), true, frame, | 
|   512           base::Bind(callback, present_time)); |   540           base::Bind(callback, present_time)); | 
|   513     } |   541     } | 
|   514   } |   542   } | 
|   515  |   543  | 
|   516   CGLFlushDrawable(context_->cgl_context()); |   544   if (!using_core_animation) | 
 |   545     CGLFlushDrawable(context_->cgl_context()); | 
|   517  |   546  | 
|   518   latency_info_.swap_timestamp = base::TimeTicks::HighResNow(); |   547   latency_info_.swap_timestamp = base::TimeTicks::HighResNow(); | 
|   519   RenderWidgetHostImpl::CompositorFrameDrawn(latency_info_); |   548   RenderWidgetHostImpl::CompositorFrameDrawn(latency_info_); | 
|   520   latency_info_.Clear(); |   549   latency_info_.Clear(); | 
|   521  |   550  | 
|   522   // For latency_tests.cc: |   551   // For latency_tests.cc: | 
|   523   UNSHIPPED_TRACE_EVENT_INSTANT0("test_gpu", "CompositorSwapBuffersComplete", |   552   UNSHIPPED_TRACE_EVENT_INSTANT0("test_gpu", "CompositorSwapBuffersComplete", | 
|   524                                  TRACE_EVENT_SCOPE_THREAD); |   553                                  TRACE_EVENT_SCOPE_THREAD); | 
|   525  |   554  | 
|   526   // Try to finish previous copy requests after flush to get better pipelining. |   555   // Try to finish previous copy requests after flush to get better pipelining. | 
|   527   std::vector<base::Closure> copy_done_callbacks; |   556   std::vector<base::Closure> copy_done_callbacks; | 
|   528   FinishAllCopiesWithinContext(©_done_callbacks); |   557   FinishAllCopiesWithinContext(©_done_callbacks); | 
|   529  |   558  | 
|   530   CGLSetCurrentContext(0); |   559   if (!using_core_animation) | 
 |   560     CGLSetCurrentContext(0); | 
|   531  |   561  | 
|   532   if (!copy_done_callback.is_null()) |   562   if (!copy_done_callback.is_null()) | 
|   533     copy_done_callbacks.push_back(copy_done_callback); |   563     copy_done_callbacks.push_back(copy_done_callback); | 
|   534   for (size_t i = 0; i < copy_done_callbacks.size(); ++i) |   564   for (size_t i = 0; i < copy_done_callbacks.size(); ++i) | 
|   535     copy_done_callbacks[i].Run(); |   565     copy_done_callbacks[i].Run(); | 
|   536  |   566  | 
|   537   StartOrContinueDisplayLink(); |   567   StartOrContinueDisplayLink(); | 
|   538  |   568  | 
|   539   if (!is_vsync_disabled()) |   569   if (!is_vsync_disabled()) | 
|   540     RateLimitDraws(); |   570     RateLimitDraws(); | 
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1076   } |  1106   } | 
|  1077 } |  1107 } | 
|  1078  |  1108  | 
|  1079 gfx::Rect CompositingIOSurfaceMac::IntersectWithIOSurface( |  1109 gfx::Rect CompositingIOSurfaceMac::IntersectWithIOSurface( | 
|  1080     const gfx::Rect& rect) const { |  1110     const gfx::Rect& rect) const { | 
|  1081   return gfx::IntersectRects(rect, |  1111   return gfx::IntersectRects(rect, | 
|  1082       gfx::ToEnclosingRect(gfx::Rect(pixel_io_surface_size_))); |  1112       gfx::ToEnclosingRect(gfx::Rect(pixel_io_surface_size_))); | 
|  1083 } |  1113 } | 
|  1084  |  1114  | 
|  1085 }  // namespace content |  1115 }  // namespace content | 
| OLD | NEW |