| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 | 80 |
| 81 // The id of the texture bound to the CHROMIUM image. | 81 // The id of the texture bound to the CHROMIUM image. |
| 82 const GLuint texture_id_; | 82 const GLuint texture_id_; |
| 83 }; | 83 }; |
| 84 #endif // USE_IOSURFACE_FOR_2D_CANVAS | 84 #endif // USE_IOSURFACE_FOR_2D_CANVAS |
| 85 | 85 |
| 86 static sk_sp<SkSurface> CreateSkSurface(GrContext* gr, | 86 static sk_sp<SkSurface> CreateSkSurface(GrContext* gr, |
| 87 const IntSize& size, | 87 const IntSize& size, |
| 88 int msaa_sample_count, | 88 int msaa_sample_count, |
| 89 OpacityMode opacity_mode, | 89 OpacityMode opacity_mode, |
| 90 sk_sp<SkColorSpace> color_space, | 90 const CanvasColorParams& color_params, |
| 91 SkColorType color_type, | |
| 92 bool* surface_is_accelerated) { | 91 bool* surface_is_accelerated) { |
| 93 if (gr) | 92 if (gr) |
| 94 gr->resetContext(); | 93 gr->resetContext(); |
| 95 | 94 |
| 96 SkAlphaType alpha_type = | 95 SkAlphaType alpha_type = |
| 97 (kOpaque == opacity_mode) ? kOpaque_SkAlphaType : kPremul_SkAlphaType; | 96 (kOpaque == opacity_mode) ? kOpaque_SkAlphaType : kPremul_SkAlphaType; |
| 98 SkImageInfo info = SkImageInfo::Make(size.Width(), size.Height(), color_type, | 97 SkImageInfo info = SkImageInfo::Make( |
| 99 alpha_type, color_space); | 98 size.Width(), size.Height(), color_params.GetSkColorType(), alpha_type, |
| 99 color_params.GetSkColorSpaceForSkSurfaces()); |
| 100 SkSurfaceProps disable_lcd_props(0, kUnknown_SkPixelGeometry); | 100 SkSurfaceProps disable_lcd_props(0, kUnknown_SkPixelGeometry); |
| 101 sk_sp<SkSurface> surface; | 101 sk_sp<SkSurface> surface; |
| 102 | 102 |
| 103 if (gr) { | 103 if (gr) { |
| 104 *surface_is_accelerated = true; | 104 *surface_is_accelerated = true; |
| 105 surface = SkSurface::MakeRenderTarget( | 105 surface = SkSurface::MakeRenderTarget( |
| 106 gr, SkBudgeted::kNo, info, msaa_sample_count, | 106 gr, SkBudgeted::kNo, info, msaa_sample_count, |
| 107 kOpaque == opacity_mode ? 0 : &disable_lcd_props); | 107 kOpaque == opacity_mode ? 0 : &disable_lcd_props); |
| 108 } | 108 } |
| 109 | 109 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 122 } | 122 } |
| 123 return surface; | 123 return surface; |
| 124 } | 124 } |
| 125 | 125 |
| 126 Canvas2DLayerBridge::Canvas2DLayerBridge( | 126 Canvas2DLayerBridge::Canvas2DLayerBridge( |
| 127 std::unique_ptr<WebGraphicsContext3DProvider> context_provider, | 127 std::unique_ptr<WebGraphicsContext3DProvider> context_provider, |
| 128 const IntSize& size, | 128 const IntSize& size, |
| 129 int msaa_sample_count, | 129 int msaa_sample_count, |
| 130 OpacityMode opacity_mode, | 130 OpacityMode opacity_mode, |
| 131 AccelerationMode acceleration_mode, | 131 AccelerationMode acceleration_mode, |
| 132 const gfx::ColorSpace& color_space, | 132 const CanvasColorParams& color_params) |
| 133 bool sk_surfaces_use_color_space, | |
| 134 SkColorType color_type) | |
| 135 : context_provider_(std::move(context_provider)), | 133 : context_provider_(std::move(context_provider)), |
| 136 logger_(WTF::WrapUnique(new Logger)), | 134 logger_(WTF::WrapUnique(new Logger)), |
| 137 weak_ptr_factory_(this), | 135 weak_ptr_factory_(this), |
| 138 image_buffer_(0), | 136 image_buffer_(0), |
| 139 msaa_sample_count_(msaa_sample_count), | 137 msaa_sample_count_(msaa_sample_count), |
| 140 bytes_allocated_(0), | 138 bytes_allocated_(0), |
| 141 have_recorded_draw_commands_(false), | 139 have_recorded_draw_commands_(false), |
| 142 destruction_in_progress_(false), | 140 destruction_in_progress_(false), |
| 143 filter_quality_(kLow_SkFilterQuality), | 141 filter_quality_(kLow_SkFilterQuality), |
| 144 is_hidden_(false), | 142 is_hidden_(false), |
| 145 is_deferral_enabled_(true), | 143 is_deferral_enabled_(true), |
| 146 software_rendering_while_hidden_(false), | 144 software_rendering_while_hidden_(false), |
| 147 last_image_id_(0), | 145 last_image_id_(0), |
| 148 last_filter_(GL_LINEAR), | 146 last_filter_(GL_LINEAR), |
| 149 acceleration_mode_(acceleration_mode), | 147 acceleration_mode_(acceleration_mode), |
| 150 opacity_mode_(opacity_mode), | 148 opacity_mode_(opacity_mode), |
| 151 size_(size), | 149 size_(size), |
| 152 color_space_(color_space), | 150 color_params_(color_params) { |
| 153 sk_surfaces_use_color_space_(sk_surfaces_use_color_space), | |
| 154 color_type_(color_type) { | |
| 155 DCHECK(context_provider_); | 151 DCHECK(context_provider_); |
| 156 DCHECK(!context_provider_->IsSoftwareRendering()); | 152 DCHECK(!context_provider_->IsSoftwareRendering()); |
| 157 DCHECK(color_space_.IsValid()); | 153 DCHECK(color_params_.GetGfxColorSpace().IsValid()); |
| 158 // Used by browser tests to detect the use of a Canvas2DLayerBridge. | 154 // Used by browser tests to detect the use of a Canvas2DLayerBridge. |
| 159 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation", | 155 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation", |
| 160 TRACE_EVENT_SCOPE_GLOBAL); | 156 TRACE_EVENT_SCOPE_GLOBAL); |
| 161 StartRecording(); | 157 StartRecording(); |
| 162 } | 158 } |
| 163 | 159 |
| 164 Canvas2DLayerBridge::~Canvas2DLayerBridge() { | 160 Canvas2DLayerBridge::~Canvas2DLayerBridge() { |
| 165 DCHECK(destruction_in_progress_); | 161 DCHECK(destruction_in_progress_); |
| 166 #if USE_IOSURFACE_FOR_2D_CANVAS | 162 #if USE_IOSURFACE_FOR_2D_CANVAS |
| 167 ClearCHROMIUMImageCache(); | 163 ClearCHROMIUMImageCache(); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 | 275 |
| 280 info.image_info_ = image_info; | 276 info.image_info_ = image_info; |
| 281 bool is_overlay_candidate = true; | 277 bool is_overlay_candidate = true; |
| 282 bool secure_output_only = false; | 278 bool secure_output_only = false; |
| 283 info.mailbox_ = mailbox; | 279 info.mailbox_ = mailbox; |
| 284 | 280 |
| 285 *out_mailbox = | 281 *out_mailbox = |
| 286 cc::TextureMailbox(mailbox, sync_token, texture_target, gfx::Size(size_), | 282 cc::TextureMailbox(mailbox, sync_token, texture_target, gfx::Size(size_), |
| 287 is_overlay_candidate, secure_output_only); | 283 is_overlay_candidate, secure_output_only); |
| 288 if (RuntimeEnabledFeatures::colorCorrectRenderingEnabled()) { | 284 if (RuntimeEnabledFeatures::colorCorrectRenderingEnabled()) { |
| 289 out_mailbox->set_color_space(color_space_); | 285 gfx::ColorSpace color_space = color_params_.GetGfxColorSpace(); |
| 290 image_info->gpu_memory_buffer_->SetColorSpaceForScanout(color_space_); | 286 out_mailbox->set_color_space(color_space); |
| 287 image_info->gpu_memory_buffer_->SetColorSpaceForScanout(color_space); |
| 291 } | 288 } |
| 292 | 289 |
| 293 gl->BindTexture(GC3D_TEXTURE_RECTANGLE_ARB, 0); | 290 gl->BindTexture(GC3D_TEXTURE_RECTANGLE_ARB, 0); |
| 294 | 291 |
| 295 // Because we are changing the texture binding without going through skia, | 292 // Because we are changing the texture binding without going through skia, |
| 296 // we must dirty the context. | 293 // we must dirty the context. |
| 297 gr_context->resetContext(kTextureBinding_GrGLBackendState); | 294 gr_context->resetContext(kTextureBinding_GrGLBackendState); |
| 298 | 295 |
| 299 return true; | 296 return true; |
| 300 } | 297 } |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 ©_paint); // GPU readback | 521 ©_paint); // GPU readback |
| 525 hibernation_image_ = temp_hibernation_surface->makeImageSnapshot(); | 522 hibernation_image_ = temp_hibernation_surface->makeImageSnapshot(); |
| 526 ResetSurface(); | 523 ResetSurface(); |
| 527 layer_->ClearTexture(); | 524 layer_->ClearTexture(); |
| 528 #if USE_IOSURFACE_FOR_2D_CANVAS | 525 #if USE_IOSURFACE_FOR_2D_CANVAS |
| 529 ClearCHROMIUMImageCache(); | 526 ClearCHROMIUMImageCache(); |
| 530 #endif // USE_IOSURFACE_FOR_2D_CANVAS | 527 #endif // USE_IOSURFACE_FOR_2D_CANVAS |
| 531 logger_->DidStartHibernating(); | 528 logger_->DidStartHibernating(); |
| 532 } | 529 } |
| 533 | 530 |
| 534 sk_sp<SkColorSpace> Canvas2DLayerBridge::SkSurfaceColorSpace() const { | |
| 535 if (sk_surfaces_use_color_space_) | |
| 536 return color_space_.ToSkColorSpace(); | |
| 537 return nullptr; | |
| 538 } | |
| 539 | |
| 540 void Canvas2DLayerBridge::ReportSurfaceCreationFailure() { | 531 void Canvas2DLayerBridge::ReportSurfaceCreationFailure() { |
| 541 if (!surface_creation_failed_at_least_once_) { | 532 if (!surface_creation_failed_at_least_once_) { |
| 542 // Only count the failure once per instance so that the histogram may | 533 // Only count the failure once per instance so that the histogram may |
| 543 // reflect the proportion of Canvas2DLayerBridge instances with surface | 534 // reflect the proportion of Canvas2DLayerBridge instances with surface |
| 544 // allocation failures. | 535 // allocation failures. |
| 545 CanvasMetrics::CountCanvasContextUsage( | 536 CanvasMetrics::CountCanvasContextUsage( |
| 546 CanvasMetrics::kGPUAccelerated2DCanvasSurfaceCreationFailed); | 537 CanvasMetrics::kGPUAccelerated2DCanvasSurfaceCreationFailed); |
| 547 surface_creation_failed_at_least_once_ = true; | 538 surface_creation_failed_at_least_once_ = true; |
| 548 } | 539 } |
| 549 } | 540 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 560 bool want_acceleration = ShouldAccelerate(hint); | 551 bool want_acceleration = ShouldAccelerate(hint); |
| 561 if (CANVAS2D_BACKGROUND_RENDER_SWITCH_TO_CPU && IsHidden() && | 552 if (CANVAS2D_BACKGROUND_RENDER_SWITCH_TO_CPU && IsHidden() && |
| 562 want_acceleration) { | 553 want_acceleration) { |
| 563 want_acceleration = false; | 554 want_acceleration = false; |
| 564 software_rendering_while_hidden_ = true; | 555 software_rendering_while_hidden_ = true; |
| 565 } | 556 } |
| 566 | 557 |
| 567 bool surface_is_accelerated; | 558 bool surface_is_accelerated; |
| 568 surface_ = CreateSkSurface( | 559 surface_ = CreateSkSurface( |
| 569 want_acceleration ? context_provider_->GetGrContext() : nullptr, size_, | 560 want_acceleration ? context_provider_->GetGrContext() : nullptr, size_, |
| 570 msaa_sample_count_, opacity_mode_, SkSurfaceColorSpace(), color_type_, | 561 msaa_sample_count_, opacity_mode_, color_params_, |
| 571 &surface_is_accelerated); | 562 &surface_is_accelerated); |
| 572 surface_paint_canvas_ = | 563 surface_paint_canvas_ = |
| 573 WTF::WrapUnique(new SkiaPaintCanvas(surface_->getCanvas())); | 564 WTF::WrapUnique(new SkiaPaintCanvas(surface_->getCanvas())); |
| 574 | 565 |
| 575 if (surface_) { | 566 if (surface_) { |
| 576 // Always save an initial frame, to support resetting the top level matrix | 567 // Always save an initial frame, to support resetting the top level matrix |
| 577 // and clip. | 568 // and clip. |
| 578 surface_paint_canvas_->save(); | 569 surface_paint_canvas_->save(); |
| 579 } else { | 570 } else { |
| 580 ReportSurfaceCreationFailure(); | 571 ReportSurfaceCreationFailure(); |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 780 | 771 |
| 781 if (have_recorded_draw_commands_ && GetOrCreateSurface()) { | 772 if (have_recorded_draw_commands_ && GetOrCreateSurface()) { |
| 782 TRACE_EVENT0("cc", "Canvas2DLayerBridge::flushRecordingOnly"); | 773 TRACE_EVENT0("cc", "Canvas2DLayerBridge::flushRecordingOnly"); |
| 783 | 774 |
| 784 // For legacy canvases, transform all input colors and images to the target | 775 // For legacy canvases, transform all input colors and images to the target |
| 785 // space using a SkCreateColorSpaceXformCanvas. This ensures blending will | 776 // space using a SkCreateColorSpaceXformCanvas. This ensures blending will |
| 786 // be done using target space pixel values. | 777 // be done using target space pixel values. |
| 787 SkCanvas* canvas = GetOrCreateSurface()->getCanvas(); | 778 SkCanvas* canvas = GetOrCreateSurface()->getCanvas(); |
| 788 std::unique_ptr<SkCanvas> color_transform_canvas; | 779 std::unique_ptr<SkCanvas> color_transform_canvas; |
| 789 if (RuntimeEnabledFeatures::colorCorrectRenderingEnabled() && | 780 if (RuntimeEnabledFeatures::colorCorrectRenderingEnabled() && |
| 790 !sk_surfaces_use_color_space_) { | 781 color_params_.UsesOutputSpaceBlending()) { |
| 791 color_transform_canvas = | 782 color_transform_canvas = SkCreateColorSpaceXformCanvas( |
| 792 SkCreateColorSpaceXformCanvas(canvas, color_space_.ToSkColorSpace()); | 783 canvas, color_params_.GetSkColorSpace()); |
| 793 canvas = color_transform_canvas.get(); | 784 canvas = color_transform_canvas.get(); |
| 794 } | 785 } |
| 795 | 786 |
| 796 recorder_->finishRecordingAsPicture()->playback(canvas); | 787 recorder_->finishRecordingAsPicture()->playback(canvas); |
| 797 if (is_deferral_enabled_) | 788 if (is_deferral_enabled_) |
| 798 StartRecording(); | 789 StartRecording(); |
| 799 have_recorded_draw_commands_ = false; | 790 have_recorded_draw_commands_ = false; |
| 800 } | 791 } |
| 801 } | 792 } |
| 802 | 793 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 869 gpu::gles2::GLES2Interface* shared_gl = nullptr; | 860 gpu::gles2::GLES2Interface* shared_gl = nullptr; |
| 870 layer_->ClearTexture(); | 861 layer_->ClearTexture(); |
| 871 context_provider_ = WTF::WrapUnique( | 862 context_provider_ = WTF::WrapUnique( |
| 872 Platform::Current()->CreateSharedOffscreenGraphicsContext3DProvider()); | 863 Platform::Current()->CreateSharedOffscreenGraphicsContext3DProvider()); |
| 873 if (context_provider_) | 864 if (context_provider_) |
| 874 shared_gl = context_provider_->ContextGL(); | 865 shared_gl = context_provider_->ContextGL(); |
| 875 | 866 |
| 876 if (shared_gl && shared_gl->GetGraphicsResetStatusKHR() == GL_NO_ERROR) { | 867 if (shared_gl && shared_gl->GetGraphicsResetStatusKHR() == GL_NO_ERROR) { |
| 877 GrContext* gr_ctx = context_provider_->GetGrContext(); | 868 GrContext* gr_ctx = context_provider_->GetGrContext(); |
| 878 bool surface_is_accelerated; | 869 bool surface_is_accelerated; |
| 879 sk_sp<SkSurface> surface(CreateSkSurface( | 870 sk_sp<SkSurface> surface(CreateSkSurface(gr_ctx, size_, msaa_sample_count_, |
| 880 gr_ctx, size_, msaa_sample_count_, opacity_mode_, SkSurfaceColorSpace(), | 871 opacity_mode_, color_params_, |
| 881 color_type_, &surface_is_accelerated)); | 872 &surface_is_accelerated)); |
| 882 if (!surface_) | 873 if (!surface_) |
| 883 ReportSurfaceCreationFailure(); | 874 ReportSurfaceCreationFailure(); |
| 884 | 875 |
| 885 // The current paradigm does not support switching from accelerated to | 876 // The current paradigm does not support switching from accelerated to |
| 886 // non-accelerated, which would be tricky due to changes to the layer tree, | 877 // non-accelerated, which would be tricky due to changes to the layer tree, |
| 887 // which can only happen at specific times during the document lifecycle. | 878 // which can only happen at specific times during the document lifecycle. |
| 888 // Therefore, we can only accept the restored surface if it is accelerated. | 879 // Therefore, we can only accept the restored surface if it is accelerated. |
| 889 if (surface && surface_is_accelerated) { | 880 if (surface && surface_is_accelerated) { |
| 890 surface_ = std::move(surface); | 881 surface_ = std::move(surface); |
| 891 // FIXME: draw sad canvas picture into new buffer crbug.com/243842 | 882 // FIXME: draw sad canvas picture into new buffer crbug.com/243842 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 938 // Early exit if canvas was not drawn to since last prepareMailbox. | 929 // Early exit if canvas was not drawn to since last prepareMailbox. |
| 939 GLenum filter = GetGLFilter(); | 930 GLenum filter = GetGLFilter(); |
| 940 if (image->uniqueID() == last_image_id_ && filter == last_filter_) | 931 if (image->uniqueID() == last_image_id_ && filter == last_filter_) |
| 941 return false; | 932 return false; |
| 942 last_image_id_ = image->uniqueID(); | 933 last_image_id_ = image->uniqueID(); |
| 943 last_filter_ = filter; | 934 last_filter_ = filter; |
| 944 | 935 |
| 945 if (!PrepareMailboxFromImage(std::move(image), out_mailbox)) | 936 if (!PrepareMailboxFromImage(std::move(image), out_mailbox)) |
| 946 return false; | 937 return false; |
| 947 out_mailbox->set_nearest_neighbor(GetGLFilter() == GL_NEAREST); | 938 out_mailbox->set_nearest_neighbor(GetGLFilter() == GL_NEAREST); |
| 948 out_mailbox->set_color_space(color_space_); | 939 out_mailbox->set_color_space(color_params_.GetGfxColorSpace()); |
| 949 | 940 |
| 950 auto func = | 941 auto func = |
| 951 WTF::Bind(&Canvas2DLayerBridge::MailboxReleased, | 942 WTF::Bind(&Canvas2DLayerBridge::MailboxReleased, |
| 952 weak_ptr_factory_.CreateWeakPtr(), out_mailbox->mailbox()); | 943 weak_ptr_factory_.CreateWeakPtr(), out_mailbox->mailbox()); |
| 953 *out_release_callback = | 944 *out_release_callback = |
| 954 cc::SingleReleaseCallback::Create(ConvertToBaseCallback(std::move(func))); | 945 cc::SingleReleaseCallback::Create(ConvertToBaseCallback(std::move(func))); |
| 955 return true; | 946 return true; |
| 956 } | 947 } |
| 957 | 948 |
| 958 void Canvas2DLayerBridge::MailboxReleased(const gpu::Mailbox& mailbox, | 949 void Canvas2DLayerBridge::MailboxReleased(const gpu::Mailbox& mailbox, |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1130 default; | 1121 default; |
| 1131 | 1122 |
| 1132 void Canvas2DLayerBridge::Logger::ReportHibernationEvent( | 1123 void Canvas2DLayerBridge::Logger::ReportHibernationEvent( |
| 1133 HibernationEvent event) { | 1124 HibernationEvent event) { |
| 1134 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernation_histogram, | 1125 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernation_histogram, |
| 1135 ("Canvas.HibernationEvents", kHibernationEventCount)); | 1126 ("Canvas.HibernationEvents", kHibernationEventCount)); |
| 1136 hibernation_histogram.Count(event); | 1127 hibernation_histogram.Count(event); |
| 1137 } | 1128 } |
| 1138 | 1129 |
| 1139 } // namespace blink | 1130 } // namespace blink |
| OLD | NEW |