| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #import <Cocoa/Cocoa.h> | 5 #import <Cocoa/Cocoa.h> |
| 6 | 6 |
| 7 #include "content/browser/compositor/software_output_device_mac.h" | 7 #include "content/browser/compositor/software_output_device_mac.h" |
| 8 | 8 |
| 9 #include "third_party/skia/include/core/SkCanvas.h" |
| 9 #include "ui/accelerated_widget_mac/accelerated_widget_mac.h" | 10 #include "ui/accelerated_widget_mac/accelerated_widget_mac.h" |
| 10 #include "ui/compositor/compositor.h" | 11 #include "ui/compositor/compositor.h" |
| 12 #include "ui/gfx/skia_util.h" |
| 11 | 13 |
| 12 namespace content { | 14 namespace content { |
| 13 | 15 |
| 14 SoftwareOutputDeviceMac::SoftwareOutputDeviceMac(ui::Compositor* compositor) | 16 SoftwareOutputDeviceMac::SoftwareOutputDeviceMac(ui::Compositor* compositor) |
| 15 : compositor_(compositor) { | 17 : compositor_(compositor), scale_factor_(1), current_index_(0) {} |
| 16 } | |
| 17 | 18 |
| 18 SoftwareOutputDeviceMac::~SoftwareOutputDeviceMac() { | 19 SoftwareOutputDeviceMac::~SoftwareOutputDeviceMac() { |
| 19 } | 20 } |
| 20 | 21 |
| 22 void SoftwareOutputDeviceMac::Resize(const gfx::Size& pixel_size, |
| 23 float scale_factor) { |
| 24 if (pixel_size_ == pixel_size && scale_factor_ == scale_factor) |
| 25 return; |
| 26 |
| 27 pixel_size_ = pixel_size; |
| 28 scale_factor_ = scale_factor; |
| 29 |
| 30 DiscardBackbuffer(); |
| 31 } |
| 32 |
| 33 void SoftwareOutputDeviceMac::CopyPreviousBufferDamage( |
| 34 const gfx::Rect& new_damage_rect) { |
| 35 TRACE_EVENT0("browser", "CopyPreviousBufferDamage"); |
| 36 |
| 37 // The region to copy is the region drawn last frame, minus the region that |
| 38 // is drawn this frame. |
| 39 SkRegion copy_region( |
| 40 SkRegion(gfx::RectToSkIRect(previous_buffer_damage_rect_))); |
| 41 bool copy_region_nonempty = copy_region.op( |
| 42 gfx::RectToSkIRect(new_damage_rect), SkRegion::kDifference_Op); |
| 43 previous_buffer_damage_rect_ = new_damage_rect; |
| 44 |
| 45 if (!copy_region_nonempty) |
| 46 return; |
| 47 |
| 48 { |
| 49 TRACE_EVENT0("browser", "IOSurfaceLock"); |
| 50 IOReturn io_result = IOSurfaceLock( |
| 51 io_surfaces_[!current_index_], |
| 52 kIOSurfaceLockReadOnly | kIOSurfaceLockAvoidSync, nullptr); |
| 53 if (io_result) { |
| 54 LOG(ERROR) << "Failed to lock previous IOSurface " << io_result; |
| 55 return; |
| 56 } |
| 57 } |
| 58 |
| 59 uint8_t* pixels = reinterpret_cast<uint8_t*>( |
| 60 IOSurfaceGetBaseAddress(io_surfaces_[!current_index_])); |
| 61 size_t pitch = IOSurfaceGetBytesPerRow(io_surfaces_[!current_index_]); |
| 62 size_t bytes_per_element = 4; |
| 63 for (SkRegion::Iterator it(copy_region); !it.done(); it.next()) { |
| 64 const SkIRect& rect = it.rect(); |
| 65 canvas_->writePixels( |
| 66 SkImageInfo::MakeN32Premul(rect.width(), rect.height()), |
| 67 pixels + bytes_per_element * rect.x() + pitch * rect.y(), pitch, |
| 68 rect.x(), rect.y()); |
| 69 } |
| 70 |
| 71 { |
| 72 TRACE_EVENT0("browser", "IOSurfaceUnlock"); |
| 73 IOReturn io_result = IOSurfaceUnlock( |
| 74 io_surfaces_[!current_index_], |
| 75 kIOSurfaceLockReadOnly | kIOSurfaceLockAvoidSync, nullptr); |
| 76 if (io_result) { |
| 77 LOG(ERROR) << "Failed to unlock previous IOSurface " << io_result; |
| 78 } |
| 79 } |
| 80 } |
| 81 |
| 82 SkCanvas* SoftwareOutputDeviceMac::BeginPaint( |
| 83 const gfx::Rect& new_damage_rect) { |
| 84 for (int i = 0; i < 2; ++i) { |
| 85 if (!io_surfaces_[i]) { |
| 86 TRACE_EVENT0("browser", "IOSurfaceCreate"); |
| 87 unsigned pixelFormat = 'BGRA'; |
| 88 unsigned bytesPerElement = 4; |
| 89 NSDictionary* options = @{ |
| 90 (id) kIOSurfaceWidth : @(pixel_size_.width()), (id) |
| 91 kIOSurfaceHeight : @(pixel_size_.height()), (id) |
| 92 kIOSurfacePixelFormat : @(pixelFormat), (id) |
| 93 kIOSurfaceBytesPerElement : @(bytesPerElement), |
| 94 }; |
| 95 io_surfaces_[i].reset(IOSurfaceCreate((CFDictionaryRef)options)); |
| 96 } |
| 97 if (!io_surfaces_[i]) { |
| 98 LOG(ERROR) << "Failed to allocateIOSurface"; |
| 99 return nullptr; |
| 100 } |
| 101 } |
| 102 |
| 103 { |
| 104 TRACE_EVENT0("browser", "IOSurfaceLock"); |
| 105 IOReturn io_result = IOSurfaceLock(io_surfaces_[current_index_], |
| 106 kIOSurfaceLockAvoidSync, nullptr); |
| 107 if (io_result) { |
| 108 LOG(ERROR) << "Failed to lock IOSurface " << io_result; |
| 109 return nullptr; |
| 110 } |
| 111 } |
| 112 |
| 113 SkPMColor* pixels = reinterpret_cast<SkPMColor*>( |
| 114 IOSurfaceGetBaseAddress(io_surfaces_[current_index_])); |
| 115 size_t pitch = IOSurfaceGetBytesPerRow(io_surfaces_[current_index_]); |
| 116 |
| 117 canvas_ = skia::AdoptRef(SkCanvas::NewRasterDirectN32( |
| 118 pixel_size_.width(), pixel_size_.height(), pixels, pitch)); |
| 119 |
| 120 CopyPreviousBufferDamage(new_damage_rect); |
| 121 return canvas_.get(); |
| 122 } |
| 123 |
| 21 void SoftwareOutputDeviceMac::EndPaint() { | 124 void SoftwareOutputDeviceMac::EndPaint() { |
| 22 SoftwareOutputDevice::EndPaint(); | 125 SoftwareOutputDevice::EndPaint(); |
| 23 ui::AcceleratedWidgetMacGotSoftwareFrame( | 126 { |
| 24 compositor_->widget(), scale_factor_, surface_->getCanvas()); | 127 TRACE_EVENT0("browser", "IOSurfaceUnlock"); |
| 128 IOReturn io_result = IOSurfaceUnlock(io_surfaces_[current_index_], |
| 129 kIOSurfaceLockAvoidSync, nullptr); |
| 130 if (io_result) { |
| 131 LOG(ERROR) << "Failed to unlock IOSurface " << io_result; |
| 132 } |
| 133 } |
| 134 |
| 135 canvas_ = nullptr; |
| 136 ui::AcceleratedWidgetMacGotIOSurfaceFrame(compositor_->widget(), |
| 137 io_surfaces_[current_index_], |
| 138 pixel_size_, scale_factor_, false); |
| 139 |
| 140 current_index_ += 1; |
| 141 current_index_ %= 2; |
| 25 } | 142 } |
| 26 | 143 |
| 144 void SoftwareOutputDeviceMac::DiscardBackbuffer() { |
| 145 for (int i = 0; i < 2; ++i) |
| 146 io_surfaces_[i].reset(); |
| 147 } |
| 148 |
| 149 void SoftwareOutputDeviceMac::EnsureBackbuffer() {} |
| 150 |
| 27 } // namespace content | 151 } // namespace content |
| OLD | NEW |