15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/software_output_device_win.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkDevice.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/compositor.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/gfx/canvas.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/gfx/canvas_skia_paint.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/gdi_util.h" 143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/gfx/skia_util.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content { 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SoftwareOutputDeviceWin::SoftwareOutputDeviceWin(ui::Compositor* compositor) 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : hwnd_(compositor->widget()), 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) is_hwnd_composited_(false) { 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(skaslev) Remove this when crbug.com/180702 is fixed. 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LONG style = GetWindowLong(hwnd_, GWL_EXSTYLE); 250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) is_hwnd_composited_ = !!(style & WS_EX_COMPOSITED); 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SoftwareOutputDeviceWin::~SoftwareOutputDeviceWin() { 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void SoftwareOutputDeviceWin::Resize(const gfx::Size& viewport_pixel_size, 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) float scale_factor) { 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scale_factor_ = scale_factor; 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (viewport_pixel_size_ == viewport_pixel_size) 39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) viewport_pixel_size_ = viewport_pixel_size; 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) contents_.reset(new gfx::Canvas(viewport_pixel_size, 1.0f, true)); 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memset(&bitmap_info_, 0, sizeof(bitmap_info_)); 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gfx::CreateBitmapHeader(viewport_pixel_size_.width(), 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) viewport_pixel_size_.height(), 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &bitmap_info_.bmiHeader); 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SkCanvas* SoftwareOutputDeviceWin::BeginPaint(const gfx::Rect& damage_rect) { 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(contents_); 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) damage_rect_ = damage_rect; 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return contents_ ? contents_->sk_canvas() : NULL; 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SoftwareOutputDeviceWin::EndPaint(cc::SoftwareFrameData* frame_data) { 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(contents_); 607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(frame_data); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!contents_) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SoftwareOutputDevice::EndPaint(frame_data); 667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect rect = damage_rect_; 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) rect.Intersect(gfx::Rect(viewport_pixel_size_)); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rect.IsEmpty()) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkCanvas* canvas = contents_->sk_canvas(); 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(canvas); 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (is_hwnd_composited_) { 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RECT wr; 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GetWindowRect(hwnd_, &wr); 77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SIZE size = {wr.right - wr.left, wr.bottom - wr.top}; 78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) POINT position = {wr.left, wr.top}; 79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) POINT zero = {0, 0}; 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) BLENDFUNCTION blend = {AC_SRC_OVER, 0x00, 0xFF, AC_SRC_ALPHA}; 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DWORD style = GetWindowLong(hwnd_, GWL_EXSTYLE); 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) style &= ~WS_EX_COMPOSITED; 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) style |= WS_EX_LAYERED; 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SetWindowLong(hwnd_, GWL_EXSTYLE, style); 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) HDC dib_dc = skia::BeginPlatformPaint(canvas); 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ::UpdateLayeredWindow(hwnd_, NULL, &position, &size, dib_dc, &zero, 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RGB(0xFF, 0xFF, 0xFF), &blend, ULW_ALPHA); 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) skia::EndPlatformPaint(canvas); 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) HDC hdc = ::GetDC(hwnd_); 93424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) RECT src_rect = rect.ToRECT(); 94424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) skia::DrawToNativeContext(canvas, hdc, rect.x(), rect.y(), &src_rect); 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ::ReleaseDC(hwnd_, hdc); 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid SoftwareOutputDeviceWin::CopyToPixels(const gfx::Rect& rect, 100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch void* pixels) { 1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(contents_); 102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch SkImageInfo info = SkImageInfo::MakeN32Premul(rect.width(), rect.height()); 103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch contents_->sk_canvas()->readPixels( 104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch info, pixels, info.minRowBytes(), rect.x(), rect.y()); 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace content 108