Chromium Code Reviews| 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; | |
|
tapted
2015/10/22 08:26:49
nit: DLOG? (i.e. is this likely? There's some resi
ccameron
2015/10/22 19:26:11
Done.
| |
| 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) { | |
|
tapted
2015/10/22 08:26:49
nit: curlies not needed
ccameron
2015/10/22 19:26:11
Done.
| |
| 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)); | |
|
tapted
2015/10/22 08:26:49
CFCast<CFDictionaryRef>(options) ? (from foundatio
ccameron
2015/10/22 19:26:11
Oops -- forgot to remove the C cast. Done.
| |
| 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) { | |
|
tapted
2015/10/22 08:26:49
nit: curlies not needed
ccameron
2015/10/22 19:26:11
Done.
| |
| 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; | |
|
tapted
2015/10/22 08:26:49
current_index_ = !current_index?
ccameron
2015/10/22 19:26:11
Done.
| |
| 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 |