Commit 048f8474 authored by jamesr's avatar jamesr Committed by Commit bot

Fixes for surfaces bindings exposed by wm_flow app

DisplayManager wasn't handling multiply nested things correctly and the
client library wasn't handling uploading to multiple views from the same
application. This fixes those.  There's still some z-ordering issues that
show up pretty visibly. This hacks up texture alpha so you can see
partially through views to try to debug.

BUG=

Review URL: https://codereview.chromium.org/555953007

Cr-Commit-Position: refs/heads/master@{#294866}
parent 12f0f7db
......@@ -201,8 +201,6 @@ class RootLayoutManager : public ViewObserver {
View* content_view = view_manager_->GetViewById(content_view_id_);
content_view->SetBounds(new_bounds);
// Force the view's bitmap to be recreated
content_view->SetColor(SK_ColorBLUE);
int delta_width = new_bounds.width() - old_bounds.width();
int delta_height = new_bounds.height() - old_bounds.height();
......@@ -375,8 +373,6 @@ class WindowManager
view->SetBounds(gfx::Rect(root->bounds().size()));
content_view_id_ = view->id();
root->SetColor(SK_ColorBLUE);
Id launcher_ui_id = CreateLauncherUI();
Id control_panel_id = CreateControlPanel(view);
......
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/bind.h"
#include "mojo/application/application_runner_chromium.h"
#include "mojo/examples/wm_flow/app/embedder.mojom.h"
#include "mojo/examples/wm_flow/embedded/embeddee.mojom.h"
#include "mojo/public/cpp/application/application_connection.h"
......@@ -84,11 +85,8 @@ class WMFlowEmbedded : public mojo::ApplicationDelegate,
} // namespace examples
namespace mojo {
// static
ApplicationDelegate* ApplicationDelegate::Create() {
return new examples::WMFlowEmbedded;
MojoResult MojoMain(MojoHandle shell_handle) {
mojo::ApplicationRunnerChromium runner(new examples::WMFlowEmbedded);
return runner.Run(shell_handle);
}
} // namespace
......@@ -17,6 +17,7 @@
#include "mojo/services/public/cpp/geometry/geometry_type_converters.h"
#include "mojo/services/public/cpp/surfaces/surfaces_type_converters.h"
#include "mojo/services/public/cpp/surfaces/surfaces_utils.h"
#include "mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "ui/gfx/geometry/rect.h"
......@@ -32,10 +33,15 @@ uint32_t TextureFormat() {
}
}
BitmapUploader::BitmapUploader(SurfacesServicePtr surfaces_service,
BitmapUploader::BitmapUploader(ViewManagerClientImpl* client,
Id view_id,
SurfacesServicePtr surfaces_service,
GpuPtr gpu_service)
: surfaces_service_(surfaces_service.Pass()),
: client_(client),
view_id_(view_id),
surfaces_service_(surfaces_service.Pass()),
gpu_service_(gpu_service.Pass()),
color_(SK_ColorTRANSPARENT),
next_resource_id_(1u),
weak_factory_(this) {
surfaces_service_->CreateSurfaceConnection(base::Bind(
......@@ -54,59 +60,56 @@ BitmapUploader::~BitmapUploader() {
MojoGLES2DestroyContext(gles2_context_);
}
void BitmapUploader::OnSurfaceConnectionCreated(SurfacePtr surface,
uint32_t id_namespace) {
surface_ = surface.Pass();
surface_.set_client(this);
id_allocator_.reset(new cc::SurfaceIdAllocator(id_namespace));
if (!bitmap_.isNull()) {
Upload(bitmap_, done_callback_);
bitmap_.reset();
done_callback_.Reset();
}
void BitmapUploader::SetSize(const gfx::Size& size) {
if (size_ == size)
return;
size_ = size;
}
uint32_t BitmapUploader::BindTextureForSize(const gfx::Size size) {
// TODO(jamesr): Recycle textures.
GLuint texture = 0u;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D,
0,
TextureFormat(),
size.width(),
size.height(),
0,
TextureFormat(),
GL_UNSIGNED_BYTE,
0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
return texture;
void BitmapUploader::SetColor(SkColor color) {
if (color_ == color)
return;
color_ = color;
if (surface_)
Upload();
}
void BitmapUploader::Upload(
SkBitmap bitmap,
const base::Callback<void(SurfaceIdPtr)>& done_callback) {
if (bitmap.width() == 0 || bitmap.height() == 0) {
done_callback.Run(SurfaceId::New());
void BitmapUploader::SetBitmap(SkBitmap bitmap) {
bitmap_ = bitmap;
if (surface_)
Upload();
}
void BitmapUploader::Upload() {
if (size_.width() == 0 || size_.height() == 0) {
client_->SetSurfaceId(view_id_, SurfaceId::New());
return;
}
if (!surface_) { // Can't upload yet, store for later.
bitmap_ = bitmap;
done_callback_ = done_callback;
done_callback_ = done_callback_;
return;
}
gfx::Size bitmap_size(bitmap.width(), bitmap.height());
if (id_.is_null() || bitmap_size != surface_size_) {
if (id_.is_null() || size_ != surface_size_) {
if (!id_.is_null())
surface_->DestroySurface(SurfaceId::From(id_));
id_ = id_allocator_->GenerateId();
surface_->CreateSurface(SurfaceId::From(id_), Size::From(bitmap_size));
surface_size_ = bitmap_size;
surface_->CreateSurface(SurfaceId::From(id_), Size::From(size_));
client_->SetSurfaceId(view_id_, SurfaceId::From(id_));
surface_size_ = size_;
}
gfx::Rect bounds(size_);
PassPtr pass = CreateDefaultPass(1, bounds);
FramePtr frame = Frame::New();
frame->resources.resize(0u);
pass->quads.resize(0u);
pass->shared_quad_states.push_back(CreateDefaultSQS(size_));
if (!bitmap_.isNull()) {
gfx::Size bitmap_size(bitmap_.width(), bitmap_.height());
GLuint texture_id = BindTextureForSize(bitmap_size);
bitmap.lockPixels();
bitmap_.lockPixels();
glTexSubImage2D(GL_TEXTURE_2D,
0,
0,
......@@ -115,8 +118,8 @@ void BitmapUploader::Upload(
bitmap_size.height(),
TextureFormat(),
GL_UNSIGNED_BYTE,
bitmap.getPixels());
bitmap.unlockPixels();
bitmap_.getPixels());
bitmap_.unlockPixels();
gpu::Mailbox mailbox = gpu::Mailbox::Generate();
glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
......@@ -136,13 +139,11 @@ void BitmapUploader::Upload(
resource->is_repeated = false;
resource->is_software = false;
gfx::Rect bitmap_rect(bitmap_size);
QuadPtr quad = Quad::New();
quad->material = MATERIAL_TEXTURE_CONTENT;
quad->rect = Rect::From(bitmap_rect);
quad->opaque_rect = Rect::From(bitmap_rect);
quad->visible_rect = Rect::From(bitmap_rect);
quad->rect = Rect::From(bounds);
quad->opaque_rect = Rect::From(bounds);
quad->visible_rect = Rect::From(bounds);
quad->needs_blending = true;
quad->shared_quad_state_index = 0u;
......@@ -151,26 +152,36 @@ void BitmapUploader::Upload(
texture_state->premultiplied_alpha = true;
texture_state->uv_top_left = PointF::From(gfx::PointF(0.f, 0.f));
texture_state->uv_bottom_right = PointF::From(gfx::PointF(1.f, 1.f));
texture_state->background_color = Color::From(SK_ColorRED);
texture_state->background_color = Color::From(SkColor(SK_ColorTRANSPARENT));
for (int i = 0; i < 4; ++i)
texture_state->vertex_opacity.push_back(1.f);
texture_state->flipped = false;
frame->resources.push_back(resource.Pass());
quad->texture_quad_state = texture_state.Pass();
pass->quads.push_back(quad.Pass());
}
SharedQuadStatePtr sqs = CreateDefaultSQS(bitmap_size);
if (color_ != SK_ColorTRANSPARENT) {
QuadPtr quad = Quad::New();
quad->material = MATERIAL_SOLID_COLOR;
quad->rect = Rect::From(bounds);
quad->opaque_rect = Rect::From(gfx::Rect());
quad->visible_rect = Rect::From(bounds);
quad->needs_blending = true;
quad->shared_quad_state_index = 0u;
PassPtr pass = CreateDefaultPass(1, bitmap_rect);
SolidColorQuadStatePtr color_state = SolidColorQuadState::New();
color_state->color = Color::From(color_);
color_state->force_anti_aliasing_off = false;
quad->solid_color_quad_state = color_state.Pass();
pass->quads.push_back(quad.Pass());
pass->shared_quad_states.push_back(sqs.Pass());
}
FramePtr frame = Frame::New();
frame->resources.push_back(resource.Pass());
frame->passes.push_back(pass.Pass());
surface_->SubmitFrame(SurfaceId::From(id_), frame.Pass());
done_callback.Run(SurfaceId::From(id_));
}
void BitmapUploader::ReturnResources(Array<ReturnedResourcePtr> resources) {
......@@ -186,4 +197,31 @@ void BitmapUploader::ReturnResources(Array<ReturnedResourcePtr> resources) {
}
}
void BitmapUploader::OnSurfaceConnectionCreated(SurfacePtr surface,
uint32_t id_namespace) {
surface_ = surface.Pass();
surface_.set_client(this);
id_allocator_.reset(new cc::SurfaceIdAllocator(id_namespace));
if (color_ != SK_ColorTRANSPARENT || !bitmap_.isNull())
Upload();
}
uint32_t BitmapUploader::BindTextureForSize(const gfx::Size size) {
// TODO(jamesr): Recycle textures.
GLuint texture = 0u;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D,
0,
TextureFormat(),
size.width(),
size.height(),
0,
TextureFormat(),
GL_UNSIGNED_BYTE,
0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
return texture;
}
} // namespace mojo
......@@ -10,6 +10,7 @@
#include "base/memory/weak_ptr.h"
#include "cc/surfaces/surface_id.h"
#include "mojo/public/c/gles2/gles2.h"
#include "mojo/services/public/cpp/view_manager/types.h"
#include "mojo/services/public/interfaces/gpu/gpu.mojom.h"
#include "mojo/services/public/interfaces/surfaces/surfaces.mojom.h"
#include "mojo/services/public/interfaces/surfaces/surfaces_service.mojom.h"
......@@ -21,27 +22,37 @@ class SurfaceIdAllocator;
}
namespace mojo {
class ViewManagerClientImpl;
class BitmapUploader : public SurfaceClient {
public:
BitmapUploader(SurfacesServicePtr surfaces_service, GpuPtr gpu_service);
BitmapUploader(ViewManagerClientImpl* client,
Id view_id,
SurfacesServicePtr surfaces_service,
GpuPtr gpu_service);
virtual ~BitmapUploader();
void Upload(SkBitmap bitmap,
const base::Callback<void(SurfaceIdPtr)>& done_callback);
void SetSize(const gfx::Size& size);
void SetColor(SkColor color);
void SetBitmap(SkBitmap bitmap);
void SetDoneCallback(const base::Callback<void(SurfaceIdPtr)>& done_callback);
private:
void Upload();
void OnSurfaceConnectionCreated(SurfacePtr surface, uint32_t id_namespace);
uint32_t BindTextureForSize(const gfx::Size size);
// SurfaceClient implementation.
virtual void ReturnResources(Array<ReturnedResourcePtr> resources) OVERRIDE;
ViewManagerClientImpl* client_;
Id view_id_;
SurfacesServicePtr surfaces_service_;
GpuPtr gpu_service_;
MojoGLES2Context gles2_context_;
// Used to hold on to the bitmap until we can upload it.
gfx::Size size_;
SkColor color_;
SkBitmap bitmap_;
base::Callback<void(SurfaceIdPtr)> done_callback_;
SurfacePtr surface_;
......
......@@ -4,10 +4,15 @@
#include "mojo/services/public/cpp/view_manager/view.h"
#include "mojo/public/cpp/application/connect.h"
#include "mojo/public/cpp/application/service_provider_impl.h"
#include "mojo/public/interfaces/application/shell.mojom.h"
#include "mojo/services/public/cpp/view_manager/lib/bitmap_uploader.h"
#include "mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.h"
#include "mojo/services/public/cpp/view_manager/lib/view_private.h"
#include "mojo/services/public/cpp/view_manager/view_observer.h"
#include "mojo/services/public/interfaces/gpu/gpu.mojom.h"
#include "mojo/services/public/interfaces/surfaces/surfaces_service.mojom.h"
#include "ui/gfx/canvas.h"
namespace mojo {
......@@ -299,15 +304,20 @@ void View::SetSurfaceId(SurfaceIdPtr id) {
void View::SetContents(const SkBitmap& contents) {
if (manager_) {
static_cast<ViewManagerClientImpl*>(manager_)->SetViewContents(id_,
contents);
if (!bitmap_uploader_)
CreateBitmapUploader();
bitmap_uploader_->SetSize(bounds_.size());
bitmap_uploader_->SetBitmap(contents);
}
}
void View::SetColor(SkColor color) {
gfx::Canvas canvas(bounds_.size(), 1.0f, true);
canvas.DrawColor(color);
SetContents(skia::GetTopDevice(*canvas.sk_canvas())->accessBitmap(true));
if (manager_) {
if (!bitmap_uploader_)
CreateBitmapUploader();
bitmap_uploader_->SetSize(bounds_.size());
bitmap_uploader_->SetColor(color);
}
}
void View::SetFocus() {
......@@ -390,4 +400,20 @@ void View::LocalSetBounds(const gfx::Rect& old_bounds,
bounds_ = new_bounds;
}
void View::CreateBitmapUploader() {
ViewManagerClientImpl* vmci = static_cast<ViewManagerClientImpl*>(manager_);
SurfacesServicePtr surfaces_service;
InterfacePtr<ServiceProvider> surfaces_service_provider;
vmci->shell()->ConnectToApplication("mojo:mojo_surfaces_service",
Get(&surfaces_service_provider));
ConnectToService(surfaces_service_provider.get(), &surfaces_service);
GpuPtr gpu_service;
InterfacePtr<ServiceProvider> gpu_service_provider;
vmci->shell()->ConnectToApplication("mojo:mojo_native_viewport_service",
Get(&gpu_service_provider));
ConnectToService(gpu_service_provider.get(), &gpu_service);
bitmap_uploader_.reset(new BitmapUploader(
vmci, id_, surfaces_service.Pass(), gpu_service.Pass()));
}
} // namespace mojo
......@@ -12,14 +12,11 @@
#include "mojo/public/cpp/application/service_provider_impl.h"
#include "mojo/public/interfaces/application/service_provider.mojom.h"
#include "mojo/public/interfaces/application/shell.mojom.h"
#include "mojo/services/public/cpp/view_manager/lib/bitmap_uploader.h"
#include "mojo/services/public/cpp/view_manager/lib/view_private.h"
#include "mojo/services/public/cpp/view_manager/util.h"
#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
#include "mojo/services/public/cpp/view_manager/view_observer.h"
#include "mojo/services/public/cpp/view_manager/window_manager_delegate.h"
#include "mojo/services/public/interfaces/gpu/gpu.mojom.h"
#include "mojo/services/public/interfaces/surfaces/surfaces_service.mojom.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/codec/png_codec.h"
......@@ -97,29 +94,6 @@ class RootObserver : public ViewObserver {
DISALLOW_COPY_AND_ASSIGN(RootObserver);
};
bool CreateMapAndDupSharedBuffer(size_t size,
void** memory,
ScopedSharedBufferHandle* handle,
ScopedSharedBufferHandle* duped) {
MojoResult result = CreateSharedBuffer(NULL, size, handle);
if (result != MOJO_RESULT_OK)
return false;
DCHECK(handle->is_valid());
result = DuplicateBuffer(handle->get(), NULL, duped);
if (result != MOJO_RESULT_OK)
return false;
DCHECK(duped->is_valid());
result = MapBuffer(
handle->get(), 0, size, memory, MOJO_MAP_BUFFER_FLAG_NONE);
if (result != MOJO_RESULT_OK)
return false;
DCHECK(*memory);
return true;
}
ViewManagerClientImpl::ViewManagerClientImpl(ViewManagerDelegate* delegate,
Shell* shell)
: connected_(false),
......@@ -159,6 +133,7 @@ ViewManagerClientImpl::~ViewManagerClientImpl() {
// NOTE: we manually delete as we're a friend.
for (size_t i = 0; i < non_owned.size(); ++i)
delete non_owned[i];
delegate_->OnViewManagerDisconnected(this);
}
......@@ -211,32 +186,6 @@ void ViewManagerClientImpl::SetSurfaceId(Id view_id, SurfaceIdPtr surface_id) {
view_id, surface_id.Pass(), ActionCompletedCallback());
}
void ViewManagerClientImpl::SetViewContents(Id view_id,
const SkBitmap& contents) {
DCHECK(connected_);
if (!bitmap_uploader_) {
SurfacesServicePtr surfaces_service;
InterfacePtr<ServiceProvider> surfaces_service_provider;
shell_->ConnectToApplication("mojo:mojo_surfaces_service",
Get(&surfaces_service_provider));
ConnectToService(surfaces_service_provider.get(), &surfaces_service);
GpuPtr gpu_service;
InterfacePtr<ServiceProvider> gpu_service_provider;
shell_->ConnectToApplication("mojo:mojo_native_viewport_service",
Get(&gpu_service_provider));
ConnectToService(gpu_service_provider.get(), &gpu_service);
bitmap_uploader_.reset(
new BitmapUploader(surfaces_service.Pass(), gpu_service.Pass()));
}
bitmap_uploader_->Upload(
contents,
base::Bind(&ViewManagerClientImpl::SetSurfaceId,
// We'll destroy the bitmap_uploader before we are destroyed,
// so we can use an unretained pointer here.
base::Unretained(this),
view_id));
}
void ViewManagerClientImpl::SetFocus(Id view_id) {
window_manager_->FocusWindow(view_id, ActionCompletedCallback());
}
......
......@@ -19,7 +19,6 @@
class SkBitmap;
namespace mojo {
class BitmapUploader;
class ViewManager;
class ViewManagerDelegate;
class ViewManagerTransaction;
......@@ -54,9 +53,6 @@ class ViewManagerClientImpl : public ViewManager,
void SetBounds(Id view_id, const gfx::Rect& bounds);
void SetSurfaceId(Id view_id, SurfaceIdPtr surface_id);
// TODO(jamesr): Remove once all callers switch from SetContents to
// SetSurfaceId.
void SetViewContents(Id view_id, const SkBitmap& contents);
void SetFocus(Id view_id);
void SetVisible(Id view_id, bool visible);
......@@ -77,6 +73,8 @@ class ViewManagerClientImpl : public ViewManager,
void AddView(View* view);
void RemoveView(Id view_id);
Shell* shell() { return shell_; }
private:
friend class RootObserver;
......@@ -133,6 +131,8 @@ class ViewManagerClientImpl : public ViewManager,
void OnActionCompleted(bool success);
void OnActionCompletedWithErrorCode(ErrorCode code);
BitmapUploader* BitmapUploaderForView(Id view_id);
base::Callback<void(bool)> ActionCompletedCallback();
base::Callback<void(ErrorCode)> ActionCompletedCallbackWithErrorCode();
......@@ -158,7 +158,6 @@ class ViewManagerClientImpl : public ViewManager,
// TODO(jamesr): Remove once all callers switch from SetContents to
// SetSurfaceId.
Shell* shell_;
scoped_ptr<BitmapUploader> bitmap_uploader_;
DISALLOW_COPY_AND_ASSIGN(ViewManagerClientImpl);
};
......
......@@ -21,6 +21,7 @@ class SkBitmap;
namespace mojo {
class BitmapUploader;
class ServiceProviderImpl;
class View;
class ViewManager;
......@@ -104,6 +105,7 @@ class View {
// Returns true if the order actually changed.
bool LocalReorder(View* relative, OrderDirection direction);
void LocalSetBounds(const gfx::Rect& old_bounds, const gfx::Rect& new_bounds);
void CreateBitmapUploader();
ViewManager* manager_;
Id id_;
......@@ -113,6 +115,9 @@ class View {
ObserverList<ViewObserver> observers_;
gfx::Rect bounds_;
// TODO(jamesr): Temporary, remove when all clients are using surfaces
// directly.
scoped_ptr<BitmapUploader> bitmap_uploader_;
DISALLOW_COPY_AND_ASSIGN(View);
};
......
......@@ -29,16 +29,23 @@ gfx::Rect ConvertRectToRoot(const ServerView* view, const gfx::Rect& bounds) {
return gfx::Rect(origin, bounds.size());
}
void DrawViewTree(Pass* pass, const ServerView* view) {
void DrawViewTree(Pass* pass, const ServerView* view, gfx::Vector2d offset) {
if (!view->visible())
return;
gfx::Rect node_bounds = view->bounds() + offset;
std::vector<const ServerView*> children(view->GetChildren());
for (std::vector<const ServerView*>::reverse_iterator it = children.rbegin();
it != children.rend();
++it) {
DrawViewTree(pass, *it, offset + view->bounds().OffsetFromOrigin());
}
cc::SurfaceId node_id = view->surface_id();
SurfaceQuadStatePtr surface_quad_state = SurfaceQuadState::New();
surface_quad_state->surface = SurfaceId::From(node_id);
const gfx::Rect& node_bounds = view->bounds();
gfx::Transform node_transform;
node_transform.Translate(node_bounds.x(), node_bounds.y());
......@@ -57,13 +64,6 @@ void DrawViewTree(Pass* pass, const ServerView* view) {
pass->quads.push_back(surface_quad.Pass());
pass->shared_quad_states.push_back(sqs.Pass());
std::vector<const ServerView*> children(view->GetChildren());
for (std::vector<const ServerView*>::reverse_iterator it = children.rbegin();
it != children.rend();
++it) {
DrawViewTree(pass, *it);
}
}
} // namespace
......@@ -126,7 +126,7 @@ void DisplayManager::Draw() {
PassPtr pass = CreateDefaultPass(1, gfx::Rect(bounds_));
pass->damage_rect = Rect::From(dirty_rect_);
DrawViewTree(pass.get(), connection_manager_->root());
DrawViewTree(pass.get(), connection_manager_->root(), gfx::Vector2d());
FramePtr frame = Frame::New();
frame->passes.push_back(pass.Pass());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment