Skip to content

Commit

Permalink
Remove CreateGpuMemoryBufferFromClientId and plumbing
Browse files Browse the repository at this point in the history
This interface is for an approach that will not be used.

This in effect reverts r396084, r395454, r395040, and r394958.

BUG=608026
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel

Review-Url: https://codereview.chromium.org/2087673002
Cr-Commit-Position: refs/heads/master@{#401186}
  • Loading branch information
ccameron-chromium authored and Commit bot committed Jun 22, 2016
1 parent 400201d commit 399d94a
Show file tree
Hide file tree
Showing 34 changed files with 28 additions and 309 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,6 @@ BlimpGpuMemoryBufferManager::CreateGpuMemoryBufferFromHandle(
handle.offset, handle.stride));
}

std::unique_ptr<gfx::GpuMemoryBuffer>
BlimpGpuMemoryBufferManager::CreateGpuMemoryBufferFromClientId(
int client_id,
const gfx::GpuMemoryBufferId& gpu_memory_buffer_id) {
NOTIMPLEMENTED();
return nullptr;
}

gfx::GpuMemoryBuffer*
BlimpGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer(
ClientBuffer buffer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ class BlimpGpuMemoryBufferManager : public gpu::GpuMemoryBufferManager {
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
gfx::BufferFormat format) override;
std::unique_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBufferFromClientId(
int client_id,
const gfx::GpuMemoryBufferId& gpu_memory_buffer_id) override;
gfx::GpuMemoryBuffer* GpuMemoryBufferFromClientBuffer(
ClientBuffer buffer) override;
void SetDestructionSyncToken(gfx::GpuMemoryBuffer* buffer,
Expand Down
1 change: 0 additions & 1 deletion cc/blink/web_external_texture_layer_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ bool WebExternalTextureLayerImpl::PrepareTextureMailbox(

*mailbox = cc::TextureMailbox(
name, sync_token, client_mailbox.textureTarget, size,
gfx::GpuMemoryBufferId(client_mailbox.gpuMemoryBufferId),
client_mailbox.allowOverlay, false);
}
mailbox->set_nearest_neighbor(client_mailbox.nearestNeighbor);
Expand Down
1 change: 0 additions & 1 deletion cc/ipc/cc_param_traits_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ IPC_STRUCT_TRAITS_BEGIN(cc::TransferableResource)
IPC_STRUCT_TRAITS_MEMBER(mailbox_holder)
IPC_STRUCT_TRAITS_MEMBER(read_lock_fences_enabled)
IPC_STRUCT_TRAITS_MEMBER(is_software)
IPC_STRUCT_TRAITS_MEMBER(gpu_memory_buffer_id)
IPC_STRUCT_TRAITS_MEMBER(is_overlay_candidate)
IPC_STRUCT_TRAITS_END()

Expand Down
3 changes: 0 additions & 3 deletions cc/ipc/struct_traits_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,6 @@ TEST_F(StructTraitsTest, TransferableResource) {
const uint32_t texture_target = 1337;
const bool read_lock_fences_enabled = true;
const bool is_software = false;
const int gpu_memory_buffer_id = 0xdeadbeef;
const bool is_overlay_candidate = true;

gpu::MailboxHolder mailbox_holder;
Expand All @@ -492,7 +491,6 @@ TEST_F(StructTraitsTest, TransferableResource) {
input.mailbox_holder = mailbox_holder;
input.read_lock_fences_enabled = read_lock_fences_enabled;
input.is_software = is_software;
input.gpu_memory_buffer_id.id = gpu_memory_buffer_id;
input.is_overlay_candidate = is_overlay_candidate;
mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy();
TransferableResource output;
Expand All @@ -507,7 +505,6 @@ TEST_F(StructTraitsTest, TransferableResource) {
output.mailbox_holder.texture_target);
EXPECT_EQ(read_lock_fences_enabled, output.read_lock_fences_enabled);
EXPECT_EQ(is_software, output.is_software);
EXPECT_EQ(gpu_memory_buffer_id, output.gpu_memory_buffer_id.id);
EXPECT_EQ(is_overlay_candidate, output.is_overlay_candidate);
}

Expand Down
1 change: 0 additions & 1 deletion cc/ipc/transferable_resource.mojom
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,5 @@ struct TransferableResource {
gpu.mojom.MailboxHolder mailbox_holder;
bool read_lock_fences_enabled;
bool is_software;
int32 gpu_memory_buffer_id;
bool is_overlay_candidate;
};
6 changes: 0 additions & 6 deletions cc/ipc/transferable_resource_struct_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,6 @@ struct StructTraits<cc::mojom::TransferableResource, cc::TransferableResource> {
return resource.is_software;
}

static int32_t gpu_memory_buffer_id(
const cc::TransferableResource& resource) {
return resource.gpu_memory_buffer_id.id;
}

static bool is_overlay_candidate(const cc::TransferableResource& resource) {
return resource.is_overlay_candidate;
}
Expand All @@ -62,7 +57,6 @@ struct StructTraits<cc::mojom::TransferableResource, cc::TransferableResource> {
out->filter = data.filter();
out->read_lock_fences_enabled = data.read_lock_fences_enabled();
out->is_software = data.is_software();
out->gpu_memory_buffer_id.id = data.gpu_memory_buffer_id();
out->is_overlay_candidate = data.is_overlay_candidate();
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion cc/layers/texture_layer_impl_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ TEST(TextureLayerImplTest, OutputIsSecure) {
mailbox,
gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO, 0x123,
gpu::CommandBufferId::FromUnsafeValue(0x234), 0x456),
GL_TEXTURE_2D, layer_size, gfx::GpuMemoryBufferId(), false, true);
GL_TEXTURE_2D, layer_size, false, true);

TextureLayerImpl* texture_layer_impl =
impl.AddChildToRoot<TextureLayerImpl>();
Expand Down
12 changes: 6 additions & 6 deletions cc/output/gl_renderer_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1966,9 +1966,9 @@ TEST_F(GLRendererTest, DontOverlayWithCopyRequests) {
root_pass->copy_requests.push_back(
CopyOutputRequest::CreateRequest(base::Bind(&IgnoreCopyResult)));

TextureMailbox mailbox = TextureMailbox(
gpu::Mailbox::Generate(), gpu::SyncToken(), GL_TEXTURE_2D,
gfx::Size(256, 256), gfx::GpuMemoryBufferId(), true, false);
TextureMailbox mailbox =
TextureMailbox(gpu::Mailbox::Generate(), gpu::SyncToken(), GL_TEXTURE_2D,
gfx::Size(256, 256), true, false);
std::unique_ptr<SingleReleaseCallbackImpl> release_callback =
SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased));
ResourceId resource_id = resource_provider->CreateResourceFromTextureMailbox(
Expand Down Expand Up @@ -2124,9 +2124,9 @@ TEST_F(GLRendererTest, OverlaySyncTokensAreProcessed) {

gpu::SyncToken sync_token(gpu::CommandBufferNamespace::GPU_IO, 0,
gpu::CommandBufferId::FromUnsafeValue(0x123), 29);
TextureMailbox mailbox = TextureMailbox(
gpu::Mailbox::Generate(), sync_token, GL_TEXTURE_2D, gfx::Size(256, 256),
gfx::GpuMemoryBufferId(), true, false);
TextureMailbox mailbox =
TextureMailbox(gpu::Mailbox::Generate(), sync_token, GL_TEXTURE_2D,
gfx::Size(256, 256), true, false);
std::unique_ptr<SingleReleaseCallbackImpl> release_callback =
SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased));
ResourceId resource_id = resource_provider->CreateResourceFromTextureMailbox(
Expand Down
6 changes: 3 additions & 3 deletions cc/output/overlay_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,9 @@ std::unique_ptr<RenderPass> CreateRenderPass() {
ResourceId CreateResource(ResourceProvider* resource_provider,
const gfx::Size& size,
bool is_overlay_candidate) {
TextureMailbox mailbox = TextureMailbox(
gpu::Mailbox::Generate(), gpu::SyncToken(), GL_TEXTURE_2D, size,
gfx::GpuMemoryBufferId(), is_overlay_candidate, false);
TextureMailbox mailbox =
TextureMailbox(gpu::Mailbox::Generate(), gpu::SyncToken(), GL_TEXTURE_2D,
size, is_overlay_candidate, false);
std::unique_ptr<SingleReleaseCallbackImpl> release_callback =
SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased));

Expand Down
7 changes: 0 additions & 7 deletions cc/resources/resource_provider.cc
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,6 @@ ResourceId ResourceProvider::CreateResourceFromTextureMailbox(
base::Owned(release_callback_impl.release()));
resource->read_lock_fences_enabled = read_lock_fences_enabled;
resource->is_overlay_candidate = mailbox.is_overlay_candidate();
resource->gpu_memory_buffer_id = mailbox.gpu_memory_buffer_id();

return id;
}
Expand Down Expand Up @@ -1104,8 +1103,6 @@ ResourceProvider::ScopedWriteLockGpuMemoryBuffer::
DCHECK(!resource_->gpu_memory_buffer);
resource_provider_->LazyCreate(resource_);
resource_->gpu_memory_buffer = std::move(gpu_memory_buffer_);
if (resource_->gpu_memory_buffer)
resource_->gpu_memory_buffer_id = resource_->gpu_memory_buffer->GetId();
resource_->allocated = true;
resource_provider_->LazyCreateImage(resource_);
resource_->dirty_image = true;
Expand Down Expand Up @@ -1392,7 +1389,6 @@ void ResourceProvider::ReceiveFromChild(
it->mailbox_holder.texture_target));
resource->read_lock_fences_enabled = it->read_lock_fences_enabled;
resource->is_overlay_candidate = it->is_overlay_candidate;
resource->gpu_memory_buffer_id = it->gpu_memory_buffer_id;
}
resource->child_id = child;
// Don't allocate a texture for a child.
Expand Down Expand Up @@ -1517,7 +1513,6 @@ void ResourceProvider::TransferResource(Resource* source,
resource->filter = source->filter;
resource->size = source->size;
resource->read_lock_fences_enabled = source->read_lock_fences_enabled;
resource->gpu_memory_buffer_id = source->gpu_memory_buffer_id;
resource->is_overlay_candidate = source->is_overlay_candidate;

if (source->type == RESOURCE_TYPE_BITMAP) {
Expand Down Expand Up @@ -1735,8 +1730,6 @@ void ResourceProvider::LazyAllocate(Resource* resource) {
gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer(
size, BufferFormat(format),
gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, gpu::kNullSurfaceHandle);
if (resource->gpu_memory_buffer)
resource->gpu_memory_buffer_id = resource->gpu_memory_buffer->GetId();
LazyCreateImage(resource);
resource->dirty_image = true;
resource->is_overlay_candidate = true;
Expand Down
1 change: 0 additions & 1 deletion cc/resources/resource_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,6 @@ class CC_EXPORT ResourceProvider
SharedBitmapId shared_bitmap_id;
SharedBitmap* shared_bitmap;
std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer;
gfx::GpuMemoryBufferId gpu_memory_buffer_id;

private:
SynchronizationState synchronization_state_ = SYNCHRONIZED;
Expand Down
2 changes: 0 additions & 2 deletions cc/resources/texture_mailbox.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,11 @@ TextureMailbox::TextureMailbox(
const gpu::SyncToken& sync_token,
uint32_t target,
const gfx::Size& size_in_pixels,
const gfx::GpuMemoryBufferId& gpu_memory_buffer_id,
bool is_overlay_candidate,
bool secure_output_only)
: mailbox_holder_(mailbox, sync_token, target),
shared_bitmap_(nullptr),
size_in_pixels_(size_in_pixels),
gpu_memory_buffer_id_(gpu_memory_buffer_id),
is_overlay_candidate_(is_overlay_candidate),
secure_output_only_(secure_output_only),
nearest_neighbor_(false) {
Expand Down
6 changes: 0 additions & 6 deletions cc/resources/texture_mailbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include "cc/base/cc_export.h"
#include "gpu/command_buffer/common/mailbox_holder.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gpu_memory_buffer.h"

namespace cc {
class SharedBitmap;
Expand All @@ -32,7 +31,6 @@ class CC_EXPORT TextureMailbox {
const gpu::SyncToken& sync_token,
uint32_t target,
const gfx::Size& size_in_pixels,
const gfx::GpuMemoryBufferId& gpu_memory_buffer_id,
bool is_overlay_candidate,
bool secure_output_only);
TextureMailbox(SharedBitmap* shared_bitmap, const gfx::Size& size_in_pixels);
Expand All @@ -58,9 +56,6 @@ class CC_EXPORT TextureMailbox {
mailbox_holder_.sync_token = sync_token;
}

gfx::GpuMemoryBufferId gpu_memory_buffer_id() const {
return gpu_memory_buffer_id_;
}
bool is_overlay_candidate() const { return is_overlay_candidate_; }
bool secure_output_only() const { return secure_output_only_; }
bool nearest_neighbor() const { return nearest_neighbor_; }
Expand All @@ -78,7 +73,6 @@ class CC_EXPORT TextureMailbox {
gpu::MailboxHolder mailbox_holder_;
SharedBitmap* shared_bitmap_;
gfx::Size size_in_pixels_;
gfx::GpuMemoryBufferId gpu_memory_buffer_id_;
bool is_overlay_candidate_;
bool secure_output_only_;
bool nearest_neighbor_;
Expand Down
2 changes: 0 additions & 2 deletions cc/resources/transferable_resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include "cc/resources/resource_format.h"
#include "gpu/command_buffer/common/mailbox_holder.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gpu_memory_buffer.h"

namespace cc {

Expand All @@ -39,7 +38,6 @@ struct CC_EXPORT TransferableResource {
gpu::MailboxHolder mailbox_holder;
bool read_lock_fences_enabled;
bool is_software;
gfx::GpuMemoryBufferId gpu_memory_buffer_id;
bool is_overlay_candidate;
};

Expand Down
7 changes: 3 additions & 4 deletions cc/resources/video_resource_updater.cc
Original file line number Diff line number Diff line change
Expand Up @@ -609,9 +609,9 @@ void VideoResourceUpdater::CopyPlaneTexture(
// Done with the source video frame texture at this point.
video_frame->UpdateReleaseSyncToken(&client);

external_resources->mailboxes.push_back(TextureMailbox(
resource->mailbox(), sync_token, GL_TEXTURE_2D, video_frame->coded_size(),
gfx::GpuMemoryBufferId(), false, false));
external_resources->mailboxes.push_back(
TextureMailbox(resource->mailbox(), sync_token, GL_TEXTURE_2D,
video_frame->coded_size(), false, false));

external_resources->release_callbacks.push_back(
base::Bind(&RecycleResource, AsWeakPtr(), resource->resource_id()));
Expand Down Expand Up @@ -650,7 +650,6 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes(
external_resources.mailboxes.push_back(TextureMailbox(
mailbox_holder.mailbox, mailbox_holder.sync_token,
mailbox_holder.texture_target, video_frame->coded_size(),
video_frame->texture_gpu_memory_buffer_id(i),
video_frame->metadata()->IsTrue(
media::VideoFrameMetadata::ALLOW_OVERLAY),
false));
Expand Down
20 changes: 0 additions & 20 deletions cc/test/test_gpu_memory_buffer_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -214,26 +214,6 @@ TestGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer(
return reinterpret_cast<gfx::GpuMemoryBuffer*>(buffer);
}

std::unique_ptr<gfx::GpuMemoryBuffer>
TestGpuMemoryBufferManager::CreateGpuMemoryBufferFromClientId(
int client_id,
const gfx::GpuMemoryBufferId& gpu_memory_buffer_id) {
// Check that the client and id are valid to ensure that the ResourceProvider
// is doing appropriate validation.
auto client_it = clients_.find(client_id);
DCHECK(client_it != clients_.end());
auto buffer_it = client_it->second->buffers_.find(gpu_memory_buffer_id.id);
DCHECK(buffer_it != client_it->second->buffers_.end());

gfx::GpuMemoryBuffer* found = buffer_it->second;

last_gpu_memory_buffer_id_ += 1;
std::unique_ptr<gfx::GpuMemoryBuffer> result(
new GpuMemoryBufferFromClient(this, last_gpu_memory_buffer_id_, found));
buffers_[last_gpu_memory_buffer_id_] = result.get();
return result;
}

void TestGpuMemoryBufferManager::SetDestructionSyncToken(
gfx::GpuMemoryBuffer* buffer,
const gpu::SyncToken& sync_token) {}
Expand Down
3 changes: 0 additions & 3 deletions cc/test/test_gpu_memory_buffer_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ class TestGpuMemoryBufferManager : public gpu::GpuMemoryBufferManager {
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
gfx::BufferFormat format) override;
std::unique_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBufferFromClientId(
int client_id,
const gfx::GpuMemoryBufferId& gpu_memory_buffer_id) override;
gfx::GpuMemoryBuffer* GpuMemoryBufferFromClientBuffer(
ClientBuffer buffer) override;
void SetDestructionSyncToken(gfx::GpuMemoryBuffer* buffer,
Expand Down
16 changes: 8 additions & 8 deletions components/exo/buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -427,10 +427,10 @@ std::unique_ptr<cc::SingleReleaseCallback> Buffer::ProduceTextureMailbox(
// This binds the latest contents of this buffer to |texture|.
gpu::SyncToken sync_token = texture->BindTexImage();

*texture_mailbox = cc::TextureMailbox(
texture->mailbox(), sync_token, texture_target_,
gpu_memory_buffer_->GetSize(), gpu_memory_buffer_->GetId(),
is_overlay_candidate_, secure_output_only);
*texture_mailbox =
cc::TextureMailbox(texture->mailbox(), sync_token, texture_target_,
gpu_memory_buffer_->GetSize(), is_overlay_candidate_,
secure_output_only);
// The contents texture will be released when no longer used by the
// compositor.
return cc::SingleReleaseCallback::Create(
Expand All @@ -452,10 +452,10 @@ std::unique_ptr<cc::SingleReleaseCallback> Buffer::ProduceTextureMailbox(
gpu::SyncToken sync_token = contents_texture->CopyTexImage(
texture, base::Bind(&Buffer::ReleaseContentsTexture, AsWeakPtr(),
base::Passed(&contents_texture_)));
*texture_mailbox = cc::TextureMailbox(
texture->mailbox(), sync_token, GL_TEXTURE_2D,
gpu_memory_buffer_->GetSize(), gfx::GpuMemoryBufferId(),
false /* is_overlay_candidate */, secure_output_only);
*texture_mailbox =
cc::TextureMailbox(texture->mailbox(), sync_token, GL_TEXTURE_2D,
gpu_memory_buffer_->GetSize(),
false /* is_overlay_candidate */, secure_output_only);
// The mailbox texture will be released when no longer used by the
// compositor.
return cc::SingleReleaseCallback::Create(
Expand Down
8 changes: 0 additions & 8 deletions components/mus/common/mojo_gpu_memory_buffer_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,6 @@ MojoGpuMemoryBufferManager::CreateGpuMemoryBufferFromHandle(
return nullptr;
}

std::unique_ptr<gfx::GpuMemoryBuffer>
MojoGpuMemoryBufferManager::CreateGpuMemoryBufferFromClientId(
int client_id,
const gfx::GpuMemoryBufferId& gpu_memory_buffer_id) {
NOTIMPLEMENTED();
return nullptr;
}

gfx::GpuMemoryBuffer*
MojoGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer(
ClientBuffer buffer) {
Expand Down
3 changes: 0 additions & 3 deletions components/mus/common/mojo_gpu_memory_buffer_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ class MUS_COMMON_EXPORT MojoGpuMemoryBufferManager
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
gfx::BufferFormat format) override;
std::unique_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBufferFromClientId(
int client_id,
const gfx::GpuMemoryBufferId& gpu_memory_buffer_id) override;
gfx::GpuMemoryBuffer* GpuMemoryBufferFromClientBuffer(
ClientBuffer buffer) override;
void SetDestructionSyncToken(gfx::GpuMemoryBuffer* buffer,
Expand Down
8 changes: 0 additions & 8 deletions components/mus/gpu/mus_gpu_memory_buffer_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,6 @@ MusGpuMemoryBufferManager::CreateGpuMemoryBufferFromHandle(
return nullptr;
}

std::unique_ptr<gfx::GpuMemoryBuffer>
MusGpuMemoryBufferManager::CreateGpuMemoryBufferFromClientId(
int client_id,
const gfx::GpuMemoryBufferId& gpu_memory_buffer_id) {
NOTIMPLEMENTED();
return nullptr;
}

gfx::GpuMemoryBuffer*
MusGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer(
ClientBuffer buffer) {
Expand Down
3 changes: 0 additions & 3 deletions components/mus/gpu/mus_gpu_memory_buffer_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ class MusGpuMemoryBufferManager : public gpu::GpuMemoryBufferManager {
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
gfx::BufferFormat format) override;
std::unique_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBufferFromClientId(
int client_id,
const gfx::GpuMemoryBufferId& gpu_memory_buffer_id) override;
gfx::GpuMemoryBuffer* GpuMemoryBufferFromClientBuffer(
ClientBuffer buffer) override;
void SetDestructionSyncToken(gfx::GpuMemoryBuffer* buffer,
Expand Down
Loading

0 comments on commit 399d94a

Please sign in to comment.