123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- // Copyright (c) 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 "gpu/ipc/service/gpu_channel.h"
- #include <stdint.h>
- #include "base/run_loop.h"
- #include "base/test/test_simple_task_runner.h"
- #include "build/build_config.h"
- #include "gpu/ipc/common/command_buffer_id.h"
- #include "gpu/ipc/common/gpu_channel.mojom.h"
- #include "gpu/ipc/service/gpu_channel_manager.h"
- #include "gpu/ipc/service/gpu_channel_test_common.h"
- namespace gpu {
- class GpuChannelTest : public GpuChannelTestCommon {
- public:
- GpuChannelTest() : GpuChannelTestCommon(true /* use_stub_bindings */) {}
- ~GpuChannelTest() override = default;
- };
- #if BUILDFLAG(IS_WIN)
- const SurfaceHandle kFakeSurfaceHandle = reinterpret_cast<SurfaceHandle>(1);
- #else
- const SurfaceHandle kFakeSurfaceHandle = 1;
- #endif
- TEST_F(GpuChannelTest, CreateViewCommandBufferAllowed) {
- int32_t kClientId = 1;
- bool is_gpu_host = true;
- GpuChannel* channel = CreateChannel(kClientId, is_gpu_host);
- ASSERT_TRUE(channel);
- SurfaceHandle surface_handle = kFakeSurfaceHandle;
- DCHECK_NE(surface_handle, kNullSurfaceHandle);
- int32_t kRouteId =
- static_cast<int32_t>(GpuChannelReservedRoutes::kMaxValue) + 1;
- auto init_params = mojom::CreateCommandBufferParams::New();
- init_params->surface_handle = surface_handle;
- init_params->share_group_id = MSG_ROUTING_NONE;
- init_params->stream_id = 0;
- init_params->stream_priority = SchedulingPriority::kNormal;
- init_params->attribs = ContextCreationAttribs();
- init_params->active_url = GURL();
- gpu::ContextResult result = gpu::ContextResult::kSuccess;
- gpu::Capabilities capabilities;
- CreateCommandBuffer(*channel, std::move(init_params), kRouteId,
- GetSharedMemoryRegion(), &result, &capabilities);
- EXPECT_EQ(result, gpu::ContextResult::kSuccess);
- CommandBufferStub* stub = channel->LookupCommandBuffer(kRouteId);
- ASSERT_TRUE(stub);
- }
- TEST_F(GpuChannelTest, CreateViewCommandBufferDisallowed) {
- int32_t kClientId = 1;
- bool is_gpu_host = false;
- GpuChannel* channel = CreateChannel(kClientId, is_gpu_host);
- ASSERT_TRUE(channel);
- SurfaceHandle surface_handle = kFakeSurfaceHandle;
- DCHECK_NE(surface_handle, kNullSurfaceHandle);
- int32_t kRouteId =
- static_cast<int32_t>(GpuChannelReservedRoutes::kMaxValue) + 1;
- auto init_params = mojom::CreateCommandBufferParams::New();
- init_params->surface_handle = surface_handle;
- init_params->share_group_id = MSG_ROUTING_NONE;
- init_params->stream_id = 0;
- init_params->stream_priority = SchedulingPriority::kNormal;
- init_params->attribs = ContextCreationAttribs();
- init_params->active_url = GURL();
- gpu::ContextResult result = gpu::ContextResult::kSuccess;
- gpu::Capabilities capabilities;
- CreateCommandBuffer(*channel, std::move(init_params), kRouteId,
- GetSharedMemoryRegion(), &result, &capabilities);
- EXPECT_EQ(result, gpu::ContextResult::kFatalFailure);
- CommandBufferStub* stub = channel->LookupCommandBuffer(kRouteId);
- EXPECT_FALSE(stub);
- }
- TEST_F(GpuChannelTest, CreateOffscreenCommandBuffer) {
- int32_t kClientId = 1;
- GpuChannel* channel = CreateChannel(kClientId, true);
- ASSERT_TRUE(channel);
- int32_t kRouteId =
- static_cast<int32_t>(GpuChannelReservedRoutes::kMaxValue) + 1;
- auto init_params = mojom::CreateCommandBufferParams::New();
- init_params->surface_handle = kNullSurfaceHandle;
- init_params->share_group_id = MSG_ROUTING_NONE;
- init_params->stream_id = 0;
- init_params->stream_priority = SchedulingPriority::kNormal;
- init_params->attribs = ContextCreationAttribs();
- init_params->active_url = GURL();
- gpu::ContextResult result = gpu::ContextResult::kSuccess;
- gpu::Capabilities capabilities;
- CreateCommandBuffer(*channel, std::move(init_params), kRouteId,
- GetSharedMemoryRegion(), &result, &capabilities);
- EXPECT_EQ(result, gpu::ContextResult::kSuccess);
- CommandBufferStub* stub = channel->LookupCommandBuffer(kRouteId);
- EXPECT_TRUE(stub);
- }
- TEST_F(GpuChannelTest, IncompatibleStreamIds) {
- int32_t kClientId = 1;
- GpuChannel* channel = CreateChannel(kClientId, true);
- ASSERT_TRUE(channel);
- // Create first context.
- int32_t kRouteId1 =
- static_cast<int32_t>(GpuChannelReservedRoutes::kMaxValue) + 1;
- int32_t kStreamId1 = 1;
- auto init_params = mojom::CreateCommandBufferParams::New();
- init_params->surface_handle = kNullSurfaceHandle;
- init_params->share_group_id = MSG_ROUTING_NONE;
- init_params->stream_id = kStreamId1;
- init_params->stream_priority = SchedulingPriority::kNormal;
- auto init_params2 = init_params.Clone();
- gpu::ContextResult result = gpu::ContextResult::kSuccess;
- gpu::Capabilities capabilities;
- CreateCommandBuffer(*channel, std::move(init_params), kRouteId1,
- GetSharedMemoryRegion(), &result, &capabilities);
- EXPECT_EQ(result, gpu::ContextResult::kSuccess);
- CommandBufferStub* stub = channel->LookupCommandBuffer(kRouteId1);
- EXPECT_TRUE(stub);
- // Create second context in same share group but different stream.
- int32_t kRouteId2 = kRouteId1 + 1;
- int32_t kStreamId2 = 2;
- init_params2->share_group_id = kRouteId1;
- init_params2->stream_id = kStreamId2;
- init_params2->stream_priority = SchedulingPriority::kNormal;
- CreateCommandBuffer(*channel, std::move(init_params2), kRouteId2,
- GetSharedMemoryRegion(), &result, &capabilities);
- EXPECT_EQ(result, gpu::ContextResult::kFatalFailure);
- stub = channel->LookupCommandBuffer(kRouteId2);
- EXPECT_FALSE(stub);
- }
- TEST_F(GpuChannelTest, CreateFailsIfSharedContextIsLost) {
- int32_t kClientId = 1;
- GpuChannel* channel = CreateChannel(kClientId, false);
- ASSERT_TRUE(channel);
- // Create first context, we will share this one.
- int32_t kSharedRouteId =
- static_cast<int32_t>(GpuChannelReservedRoutes::kMaxValue) + 1;
- {
- SCOPED_TRACE("kSharedRouteId");
- auto init_params = mojom::CreateCommandBufferParams::New();
- init_params->surface_handle = kNullSurfaceHandle;
- init_params->share_group_id = MSG_ROUTING_NONE;
- init_params->stream_id = 0;
- init_params->stream_priority = SchedulingPriority::kNormal;
- init_params->attribs = ContextCreationAttribs();
- init_params->active_url = GURL();
- gpu::ContextResult result = gpu::ContextResult::kSuccess;
- gpu::Capabilities capabilities;
- CreateCommandBuffer(*channel, std::move(init_params), kSharedRouteId,
- GetSharedMemoryRegion(), &result, &capabilities);
- EXPECT_EQ(result, gpu::ContextResult::kSuccess);
- }
- EXPECT_TRUE(channel->LookupCommandBuffer(kSharedRouteId));
- // This context shares with the first one, this should be possible.
- int32_t kFriendlyRouteId = kSharedRouteId + 1;
- {
- SCOPED_TRACE("kFriendlyRouteId");
- auto init_params = mojom::CreateCommandBufferParams::New();
- init_params->surface_handle = kNullSurfaceHandle;
- init_params->share_group_id = kSharedRouteId;
- init_params->stream_id = 0;
- init_params->stream_priority = SchedulingPriority::kNormal;
- init_params->attribs = ContextCreationAttribs();
- init_params->active_url = GURL();
- gpu::ContextResult result = gpu::ContextResult::kSuccess;
- gpu::Capabilities capabilities;
- CreateCommandBuffer(*channel, std::move(init_params), kFriendlyRouteId,
- GetSharedMemoryRegion(), &result, &capabilities);
- EXPECT_EQ(result, gpu::ContextResult::kSuccess);
- }
- EXPECT_TRUE(channel->LookupCommandBuffer(kFriendlyRouteId));
- // The shared context is lost.
- channel->LookupCommandBuffer(kSharedRouteId)->MarkContextLost();
- // Meanwhile another context is being made pointing to the shared one. This
- // should fail.
- int32_t kAnotherRouteId = kFriendlyRouteId + 1;
- {
- SCOPED_TRACE("kAnotherRouteId");
- auto init_params = mojom::CreateCommandBufferParams::New();
- init_params->surface_handle = kNullSurfaceHandle;
- init_params->share_group_id = kSharedRouteId;
- init_params->stream_id = 0;
- init_params->stream_priority = SchedulingPriority::kNormal;
- init_params->attribs = ContextCreationAttribs();
- init_params->active_url = GURL();
- gpu::ContextResult result = gpu::ContextResult::kSuccess;
- gpu::Capabilities capabilities;
- CreateCommandBuffer(*channel, std::move(init_params), kAnotherRouteId,
- GetSharedMemoryRegion(), &result, &capabilities);
- EXPECT_EQ(result, gpu::ContextResult::kTransientFailure);
- }
- EXPECT_FALSE(channel->LookupCommandBuffer(kAnotherRouteId));
- // The lost context is still around though (to verify the failure happened due
- // to the shared context being lost, not due to it being deleted).
- EXPECT_TRUE(channel->LookupCommandBuffer(kSharedRouteId));
- // Destroy the command buffers we initialized before destoying GL.
- channel->DestroyCommandBuffer(kFriendlyRouteId);
- channel->DestroyCommandBuffer(kSharedRouteId);
- }
- class GpuChannelExitForContextLostTest : public GpuChannelTestCommon {
- public:
- GpuChannelExitForContextLostTest()
- : GpuChannelTestCommon({EXIT_ON_CONTEXT_LOST} /* enabled_workarounds */,
- true /* use_stub_bindings */) {}
- };
- TEST_F(GpuChannelExitForContextLostTest,
- CreateFailsDuringLostContextShutdown_1) {
- int32_t kClientId = 1;
- GpuChannel* channel = CreateChannel(kClientId, false);
- ASSERT_TRUE(channel);
- // Put channel manager into shutdown state.
- channel_manager()->OnContextLost(false /* synthetic_loss */);
- // Calling OnContextLost() above may destroy the gpu channel via post task.
- // Ensure that post task has happened.
- base::RunLoop().RunUntilIdle();
- // If the channel is destroyed, then skip the test.
- if (!channel_manager()->LookupChannel(kClientId))
- return;
- // Try to create a context.
- int32_t kRouteId =
- static_cast<int32_t>(GpuChannelReservedRoutes::kMaxValue) + 1;
- auto init_params = mojom::CreateCommandBufferParams::New();
- init_params->surface_handle = kNullSurfaceHandle;
- init_params->share_group_id = MSG_ROUTING_NONE;
- init_params->stream_id = 0;
- init_params->stream_priority = SchedulingPriority::kNormal;
- init_params->attribs = ContextCreationAttribs();
- init_params->active_url = GURL();
- gpu::ContextResult result = gpu::ContextResult::kSuccess;
- gpu::Capabilities capabilities;
- CreateCommandBuffer(*channel, std::move(init_params), kRouteId,
- GetSharedMemoryRegion(), &result, &capabilities);
- EXPECT_EQ(result, gpu::ContextResult::kTransientFailure);
- EXPECT_FALSE(channel->LookupCommandBuffer(kRouteId));
- }
- TEST_F(GpuChannelExitForContextLostTest,
- CreateFailsDuringLostContextShutdown_2) {
- // Put channel manager into shutdown state. Do this before creating a channel,
- // as doing this may destroy any active channels.
- channel_manager()->OnContextLost(false /* synthetic_loss */);
- int32_t kClientId = 1;
- GpuChannel* channel = CreateChannel(kClientId, false);
- ASSERT_TRUE(channel);
- // Try to create a context.
- int32_t kRouteId =
- static_cast<int32_t>(GpuChannelReservedRoutes::kMaxValue) + 1;
- auto init_params = mojom::CreateCommandBufferParams::New();
- init_params->surface_handle = kNullSurfaceHandle;
- init_params->share_group_id = MSG_ROUTING_NONE;
- init_params->stream_id = 0;
- init_params->stream_priority = SchedulingPriority::kNormal;
- init_params->attribs = ContextCreationAttribs();
- init_params->active_url = GURL();
- gpu::ContextResult result = gpu::ContextResult::kSuccess;
- gpu::Capabilities capabilities;
- CreateCommandBuffer(*channel, std::move(init_params), kRouteId,
- GetSharedMemoryRegion(), &result, &capabilities);
- EXPECT_EQ(result, gpu::ContextResult::kTransientFailure);
- EXPECT_FALSE(channel->LookupCommandBuffer(kRouteId));
- }
- } // namespace gpu
|