flutter_flutter/sky/shell/gpu/rasterizer.cc
Adam Barth 795df1327b Plumb physical size along with SkPicture
Previously we were using the cull rect of the SkPicture to size the GPU buffer,
but Skia is too smart and shrinkwraps the cull rect, which meant we weren't
sizing the GPU buffer to the right size.

Fixes #814
2015-08-26 09:26:51 -07:00

97 lines
2.8 KiB
C++

// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "sky/shell/gpu/rasterizer.h"
#include "base/trace_event/trace_event.h"
#include "sky/shell/gpu/ganesh_context.h"
#include "sky/shell/gpu/ganesh_surface.h"
#include "sky/shell/gpu/picture_serializer.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_share_group.h"
#include "ui/gl/gl_surface.h"
namespace sky {
namespace shell {
Rasterizer::Rasterizer()
: share_group_(new gfx::GLShareGroup()), weak_factory_(this) {
}
Rasterizer::~Rasterizer() {
}
base::WeakPtr<Rasterizer> Rasterizer::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
void Rasterizer::OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) {
surface_ = gfx::GLSurface::CreateViewGLSurface(widget,
gfx::SurfaceConfiguration());
CHECK(surface_) << "GLSurface required.";
}
void Rasterizer::Draw(PassRefPtr<SkPicture> picture, gfx::Size size) {
TRACE_EVENT0("sky", "Rasterizer::Draw");
if (!surface_)
return;
if (surface_->GetSize() != size)
surface_->Resize(size);
EnsureGLContext();
CHECK(context_->MakeCurrent(surface_.get()));
EnsureGaneshSurface(surface_->GetBackingFrameBufferObject(), size);
DrawPicture(picture.get());
surface_->SwapBuffers();
// SerializePicture("/data/data/org.domokit.sky.shell/cache/layer0.skp", picture.get());
}
void Rasterizer::DrawPicture(SkPicture* picture) {
TRACE_EVENT0("sky", "Rasterizer::DrawPicture");
SkCanvas* canvas = ganesh_surface_->canvas();
canvas->clear(SK_ColorBLACK);
canvas->drawPicture(picture);
canvas->flush();
}
void Rasterizer::OnOutputSurfaceDestroyed() {
if (context_) {
CHECK(context_->MakeCurrent(surface_.get()));
ganesh_surface_.reset();
ganesh_context_.reset();
context_ = nullptr;
}
CHECK(!ganesh_surface_);
CHECK(!ganesh_context_);
CHECK(!context_);
surface_ = nullptr;
}
void Rasterizer::EnsureGLContext() {
if (context_)
return;
context_ = gfx::GLContext::CreateGLContext(share_group_.get(), surface_.get(),
gfx::PreferIntegratedGpu);
CHECK(context_) << "GLContext required.";
CHECK(context_->MakeCurrent(surface_.get()));
ganesh_context_.reset(new GaneshContext(context_.get()));
}
void Rasterizer::EnsureGaneshSurface(intptr_t window_fbo,
const gfx::Size& size) {
if (!ganesh_surface_ || ganesh_surface_->size() != size)
ganesh_surface_.reset(
new GaneshSurface(window_fbo, ganesh_context_.get(), size));
}
} // namespace shell
} // namespace sky