Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
4b3db52b
Commit
4b3db52b
authored
Nov 27, 2013
by
Henri Verbeet
Committed by
Alexandre Julliard
Nov 27, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wined3d: Merge the texture creation functions.
parent
8c08faba
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
50 additions
and
105 deletions
+50
-105
texture.c
dlls/d3d10core/texture.c
+3
-3
device.c
dlls/d3d8/device.c
+2
-2
texture.c
dlls/d3d8/texture.c
+3
-3
device.c
dlls/d3d9/device.c
+2
-2
texture.c
dlls/d3d9/texture.c
+3
-3
ddraw.c
dlls/ddraw/ddraw.c
+1
-1
surface.c
dlls/ddraw/surface.c
+8
-11
device.c
dlls/wined3d/device.c
+2
-2
surface.c
dlls/wined3d/surface.c
+2
-1
texture.c
dlls/wined3d/texture.c
+22
-68
wined3d.spec
dlls/wined3d/wined3d.spec
+1
-3
wined3d.h
include/wine/wined3d.h
+1
-6
No files found.
dlls/d3d10core/texture.c
View file @
4b3db52b
...
...
@@ -274,7 +274,7 @@ HRESULT d3d10_texture2d_init(struct d3d10_texture2d *texture, struct d3d10_devic
wined3d_desc
.
depth
=
1
;
wined3d_desc
.
size
=
0
;
if
(
FAILED
(
hr
=
wined3d_texture_create
_2d
(
device
->
wined3d_device
,
&
wined3d_desc
,
desc
->
MipLevels
,
if
(
FAILED
(
hr
=
wined3d_texture_create
(
device
->
wined3d_device
,
&
wined3d_desc
,
desc
->
MipLevels
,
0
,
texture
,
&
d3d10_texture2d_wined3d_parent_ops
,
&
texture
->
wined3d_texture
)))
{
WARN
(
"Failed to create wined3d texture, hr %#x.
\n
"
,
hr
);
...
...
@@ -492,8 +492,8 @@ HRESULT d3d10_texture3d_init(struct d3d10_texture3d *texture, struct d3d10_devic
wined3d_desc
.
depth
=
desc
->
Depth
;
wined3d_desc
.
size
=
0
;
if
(
FAILED
(
hr
=
wined3d_texture_create
_3d
(
device
->
wined3d_device
,
&
wined3d_desc
,
desc
->
MipLevels
,
texture
,
&
d3d10_texture3d_wined3d_parent_ops
,
&
texture
->
wined3d_texture
)))
if
(
FAILED
(
hr
=
wined3d_texture_create
(
device
->
wined3d_device
,
&
wined3d_desc
,
desc
->
MipLevels
,
0
,
texture
,
&
d3d10_texture3d_wined3d_parent_ops
,
&
texture
->
wined3d_texture
)))
{
WARN
(
"Failed to create wined3d texture, hr %#x.
\n
"
,
hr
);
return
hr
;
...
...
dlls/d3d8/device.c
View file @
4b3db52b
...
...
@@ -905,7 +905,7 @@ static HRESULT d3d8_device_create_surface(struct d3d8_device *device, UINT width
wined3d_mutex_lock
();
if
(
FAILED
(
hr
=
wined3d_texture_create
_2d
(
device
->
wined3d_device
,
&
desc
,
if
(
FAILED
(
hr
=
wined3d_texture_create
(
device
->
wined3d_device
,
&
desc
,
1
,
flags
,
NULL
,
&
d3d8_null_wined3d_parent_ops
,
&
texture
)))
{
wined3d_mutex_unlock
();
...
...
@@ -2965,7 +2965,7 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic
texture_desc
=
*
desc
;
texture_desc
.
resource_type
=
WINED3D_RTYPE_TEXTURE
;
if
(
FAILED
(
hr
=
wined3d_texture_create
_2d
(
device
->
wined3d_device
,
&
texture_desc
,
1
,
if
(
FAILED
(
hr
=
wined3d_texture_create
(
device
->
wined3d_device
,
&
texture_desc
,
1
,
WINED3D_SURFACE_MAPPABLE
,
&
device
->
IDirect3DDevice8_iface
,
&
d3d8_null_wined3d_parent_ops
,
&
texture
)))
{
WARN
(
"Failed to create texture, hr %#x.
\n
"
,
hr
);
...
...
dlls/d3d8/texture.c
View file @
4b3db52b
...
...
@@ -1208,7 +1208,7 @@ HRESULT texture_init(struct d3d8_texture *texture, struct d3d8_device *device,
surface_flags
|=
WINED3D_SURFACE_MAPPABLE
;
wined3d_mutex_lock
();
hr
=
wined3d_texture_create
_2d
(
device
->
wined3d_device
,
&
desc
,
levels
,
surface_flags
,
hr
=
wined3d_texture_create
(
device
->
wined3d_device
,
&
desc
,
levels
,
surface_flags
,
texture
,
&
d3d8_texture_wined3d_parent_ops
,
&
texture
->
wined3d_texture
);
wined3d_mutex_unlock
();
if
(
FAILED
(
hr
))
...
...
@@ -1249,7 +1249,7 @@ HRESULT cubetexture_init(struct d3d8_texture *texture, struct d3d8_device *devic
surface_flags
|=
WINED3D_SURFACE_MAPPABLE
;
wined3d_mutex_lock
();
hr
=
wined3d_texture_create
_cube
(
device
->
wined3d_device
,
&
desc
,
levels
,
surface_flags
,
hr
=
wined3d_texture_create
(
device
->
wined3d_device
,
&
desc
,
levels
,
surface_flags
,
texture
,
&
d3d8_texture_wined3d_parent_ops
,
&
texture
->
wined3d_texture
);
wined3d_mutex_unlock
();
if
(
FAILED
(
hr
))
...
...
@@ -1286,7 +1286,7 @@ HRESULT volumetexture_init(struct d3d8_texture *texture, struct d3d8_device *dev
desc
.
size
=
0
;
wined3d_mutex_lock
();
hr
=
wined3d_texture_create
_3d
(
device
->
wined3d_device
,
&
desc
,
levels
,
hr
=
wined3d_texture_create
(
device
->
wined3d_device
,
&
desc
,
levels
,
0
,
texture
,
&
d3d8_texture_wined3d_parent_ops
,
&
texture
->
wined3d_texture
);
wined3d_mutex_unlock
();
if
(
FAILED
(
hr
))
...
...
dlls/d3d9/device.c
View file @
4b3db52b
...
...
@@ -938,7 +938,7 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width
wined3d_mutex_lock
();
if
(
FAILED
(
hr
=
wined3d_texture_create
_2d
(
device
->
wined3d_device
,
&
desc
,
if
(
FAILED
(
hr
=
wined3d_texture_create
(
device
->
wined3d_device
,
&
desc
,
1
,
flags
,
NULL
,
&
d3d9_null_wined3d_parent_ops
,
&
texture
)))
{
wined3d_mutex_unlock
();
...
...
@@ -3354,7 +3354,7 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic
texture_desc
=
*
desc
;
texture_desc
.
resource_type
=
WINED3D_RTYPE_TEXTURE
;
if
(
FAILED
(
hr
=
wined3d_texture_create
_2d
(
device
->
wined3d_device
,
&
texture_desc
,
1
,
if
(
FAILED
(
hr
=
wined3d_texture_create
(
device
->
wined3d_device
,
&
texture_desc
,
1
,
WINED3D_SURFACE_MAPPABLE
,
container_parent
,
&
d3d9_null_wined3d_parent_ops
,
&
texture
)))
{
WARN
(
"Failed to create texture, hr %#x.
\n
"
,
hr
);
...
...
dlls/d3d9/texture.c
View file @
4b3db52b
...
...
@@ -1332,7 +1332,7 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
surface_flags
|=
WINED3D_SURFACE_MAPPABLE
;
wined3d_mutex_lock
();
hr
=
wined3d_texture_create
_2d
(
device
->
wined3d_device
,
&
desc
,
levels
,
surface_flags
,
hr
=
wined3d_texture_create
(
device
->
wined3d_device
,
&
desc
,
levels
,
surface_flags
,
texture
,
&
d3d9_texture_wined3d_parent_ops
,
&
texture
->
wined3d_texture
);
wined3d_mutex_unlock
();
if
(
FAILED
(
hr
))
...
...
@@ -1373,7 +1373,7 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic
surface_flags
|=
WINED3D_SURFACE_MAPPABLE
;
wined3d_mutex_lock
();
hr
=
wined3d_texture_create
_cube
(
device
->
wined3d_device
,
&
desc
,
levels
,
surface_flags
,
hr
=
wined3d_texture_create
(
device
->
wined3d_device
,
&
desc
,
levels
,
surface_flags
,
texture
,
&
d3d9_texture_wined3d_parent_ops
,
&
texture
->
wined3d_texture
);
wined3d_mutex_unlock
();
if
(
FAILED
(
hr
))
...
...
@@ -1410,7 +1410,7 @@ HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *dev
desc
.
size
=
0
;
wined3d_mutex_lock
();
hr
=
wined3d_texture_create
_3d
(
device
->
wined3d_device
,
&
desc
,
levels
,
hr
=
wined3d_texture_create
(
device
->
wined3d_device
,
&
desc
,
levels
,
0
,
texture
,
&
d3d9_texture_wined3d_parent_ops
,
&
texture
->
wined3d_texture
);
wined3d_mutex_unlock
();
if
(
FAILED
(
hr
))
...
...
dlls/ddraw/ddraw.c
View file @
4b3db52b
...
...
@@ -4969,7 +4969,7 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic
texture_desc
=
*
desc
;
texture_desc
.
resource_type
=
WINED3D_RTYPE_TEXTURE
;
if
(
FAILED
(
hr
=
wined3d_texture_create
_2d
(
ddraw
->
wined3d_device
,
&
texture_desc
,
1
,
if
(
FAILED
(
hr
=
wined3d_texture_create
(
ddraw
->
wined3d_device
,
&
texture_desc
,
1
,
WINED3D_SURFACE_MAPPABLE
,
ddraw
,
&
ddraw_frontbuffer_parent_ops
,
&
texture
)))
{
WARN
(
"Failed to create texture, hr %#x.
\n
"
,
hr
);
...
...
dlls/ddraw/surface.c
View file @
4b3db52b
...
...
@@ -5827,28 +5827,25 @@ HRESULT ddraw_surface_create_texture(struct ddraw *ddraw, DDSURFACEDESC2 *desc,
texture
->
version
=
version
;
copy_to_surfacedesc2
(
&
texture
->
surface_desc
,
desc
);
/* Some applications assume surfaces will always be mapped at the same
* address. Some of those also assume that this address is valid even when
* the surface isn't mapped, and that updates done this way will be
* visible on the screen. The game Nox is such an application,
* Commandos: Behind Enemy Lines is another. We set
* WINED3D_SURFACE_PIN_SYSMEM because of this. */
if
(
desc
->
ddsCaps
.
dwCaps2
&
DDSCAPS2_CUBEMAP
)
{
wined3d_desc
.
resource_type
=
WINED3D_RTYPE_CUBE_TEXTURE
;
hr
=
wined3d_texture_create_cube
(
ddraw
->
wined3d_device
,
&
wined3d_desc
,
levels
,
WINED3D_SURFACE_PIN_SYSMEM
,
texture
,
&
ddraw_texture_wined3d_parent_ops
,
&
wined3d_texture
);
layers
=
6
;
}
else
{
wined3d_desc
.
resource_type
=
WINED3D_RTYPE_TEXTURE
;
hr
=
wined3d_texture_create_2d
(
ddraw
->
wined3d_device
,
&
wined3d_desc
,
levels
,
WINED3D_SURFACE_PIN_SYSMEM
,
texture
,
&
ddraw_texture_wined3d_parent_ops
,
&
wined3d_texture
);
layers
=
1
;
}
if
(
FAILED
(
hr
))
/* Some applications assume surfaces will always be mapped at the same
* address. Some of those also assume that this address is valid even when
* the surface isn't mapped, and that updates done this way will be
* visible on the screen. The game Nox is such an application,
* Commandos: Behind Enemy Lines is another. We set
* WINED3D_SURFACE_PIN_SYSMEM because of this. */
if
(
FAILED
(
hr
=
wined3d_texture_create
(
ddraw
->
wined3d_device
,
&
wined3d_desc
,
levels
,
WINED3D_SURFACE_PIN_SYSMEM
,
texture
,
&
ddraw_texture_wined3d_parent_ops
,
&
wined3d_texture
)))
{
WARN
(
"Failed to create wined3d texture, hr %#x.
\n
"
,
hr
);
switch
(
hr
)
...
...
dlls/wined3d/device.c
View file @
4b3db52b
...
...
@@ -586,7 +586,7 @@ static void device_load_logo(struct wined3d_device *device, const char *filename
desc
.
height
=
bm
.
bmHeight
;
desc
.
depth
=
1
;
desc
.
size
=
0
;
if
(
FAILED
(
hr
=
wined3d_texture_create
_2d
(
device
,
&
desc
,
1
,
WINED3D_SURFACE_MAPPABLE
,
if
(
FAILED
(
hr
=
wined3d_texture_create
(
device
,
&
desc
,
1
,
WINED3D_SURFACE_MAPPABLE
,
NULL
,
&
wined3d_null_parent_ops
,
&
device
->
logo_texture
)))
{
ERR
(
"Wine logo requested, but failed to create texture, hr %#x.
\n
"
,
hr
);
...
...
@@ -3816,7 +3816,7 @@ static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined
desc
.
depth
=
1
;
desc
.
size
=
0
;
if
(
FAILED
(
wined3d_texture_create
_2d
(
device
,
&
desc
,
1
,
WINED3D_SURFACE_MAPPABLE
,
if
(
FAILED
(
wined3d_texture_create
(
device
,
&
desc
,
1
,
WINED3D_SURFACE_MAPPABLE
,
NULL
,
&
wined3d_null_parent_ops
,
&
texture
)))
{
ERR
(
"Failed to create cursor texture.
\n
"
);
...
...
dlls/wined3d/surface.c
View file @
4b3db52b
...
...
@@ -3074,10 +3074,11 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_surface *so
/* FIXME: Multisampled conversion? */
wined3d_resource_get_desc
(
&
source
->
resource
,
&
desc
);
desc
.
resource_type
=
WINED3D_RTYPE_TEXTURE
;
desc
.
format
=
to_fmt
;
desc
.
usage
=
0
;
desc
.
pool
=
WINED3D_POOL_SCRATCH
;
if
(
FAILED
(
wined3d_texture_create
_2d
(
source
->
resource
.
device
,
&
desc
,
1
,
if
(
FAILED
(
wined3d_texture_create
(
source
->
resource
.
device
,
&
desc
,
1
,
WINED3D_SURFACE_MAPPABLE
|
WINED3D_SURFACE_DISCARD
,
NULL
,
&
wined3d_null_parent_ops
,
&
ret
)))
{
ERR
(
"Failed to create a destination surface for conversion.
\n
"
);
...
...
dlls/wined3d/texture.c
View file @
4b3db52b
...
...
@@ -1135,7 +1135,7 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct
return
WINED3D_OK
;
}
HRESULT
CDECL
wined3d_texture_create
_2d
(
struct
wined3d_device
*
device
,
const
struct
wined3d_resource_desc
*
desc
,
HRESULT
CDECL
wined3d_texture_create
(
struct
wined3d_device
*
device
,
const
struct
wined3d_resource_desc
*
desc
,
UINT
level_count
,
DWORD
surface_flags
,
void
*
parent
,
const
struct
wined3d_parent_ops
*
parent_ops
,
struct
wined3d_texture
**
texture
)
{
...
...
@@ -1145,79 +1145,33 @@ HRESULT CDECL wined3d_texture_create_2d(struct wined3d_device *device, const str
TRACE
(
"device %p, desc %p, level_count %u, surface_flags %#x, parent %p, parent_ops %p, texture %p.
\n
"
,
device
,
desc
,
level_count
,
surface_flags
,
parent
,
parent_ops
,
texture
);
object
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
*
object
));
if
(
!
object
)
{
*
texture
=
NULL
;
return
WINED3DERR_OUTOFVIDEOMEMORY
;
}
if
(
FAILED
(
hr
=
texture_init
(
object
,
desc
,
level_count
,
surface_flags
,
device
,
parent
,
parent_ops
)))
{
WARN
(
"Failed to initialize texture, returning %#x.
\n
"
,
hr
);
HeapFree
(
GetProcessHeap
(),
0
,
object
);
*
texture
=
NULL
;
return
hr
;
}
TRACE
(
"Created texture %p.
\n
"
,
object
);
*
texture
=
object
;
return
WINED3D_OK
;
}
HRESULT
CDECL
wined3d_texture_create_3d
(
struct
wined3d_device
*
device
,
const
struct
wined3d_resource_desc
*
desc
,
UINT
level_count
,
void
*
parent
,
const
struct
wined3d_parent_ops
*
parent_ops
,
struct
wined3d_texture
**
texture
)
{
struct
wined3d_texture
*
object
;
HRESULT
hr
;
TRACE
(
"device %p, desc %p, level_count %u, parent %p, parent_ops %p, texture %p.
\n
"
,
device
,
desc
,
level_count
,
parent
,
parent_ops
,
texture
);
object
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
*
object
));
if
(
!
object
)
{
*
texture
=
NULL
;
return
WINED3DERR_OUTOFVIDEOMEMORY
;
}
if
(
FAILED
(
hr
=
volumetexture_init
(
object
,
desc
,
level_count
,
device
,
parent
,
parent_ops
)))
{
WARN
(
"Failed to initialize volumetexture, returning %#x
\n
"
,
hr
);
HeapFree
(
GetProcessHeap
(),
0
,
object
);
*
texture
=
NULL
;
return
hr
;
}
TRACE
(
"Created texture %p.
\n
"
,
object
);
*
texture
=
object
;
return
WINED3D_OK
;
}
HRESULT
CDECL
wined3d_texture_create_cube
(
struct
wined3d_device
*
device
,
const
struct
wined3d_resource_desc
*
desc
,
UINT
level_count
,
DWORD
surface_flags
,
void
*
parent
,
const
struct
wined3d_parent_ops
*
parent_ops
,
struct
wined3d_texture
**
texture
)
{
struct
wined3d_texture
*
object
;
HRESULT
hr
;
TRACE
(
"device %p, desc %p, level_count %u, surface_flags %#x, parent %p, parent_ops %p, texture %p.
\n
"
,
device
,
desc
,
level_count
,
surface_flags
,
parent
,
parent_ops
,
texture
);
if
(
!
(
object
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
*
object
))))
return
E_OUTOFMEMORY
;
object
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
*
object
));
if
(
!
object
)
switch
(
desc
->
resource_type
)
{
*
texture
=
NULL
;
return
WINED3DERR_OUTOFVIDEOMEMORY
;
case
WINED3D_RTYPE_TEXTURE
:
hr
=
texture_init
(
object
,
desc
,
level_count
,
surface_flags
,
device
,
parent
,
parent_ops
);
break
;
case
WINED3D_RTYPE_VOLUME_TEXTURE
:
hr
=
volumetexture_init
(
object
,
desc
,
level_count
,
device
,
parent
,
parent_ops
);
break
;
case
WINED3D_RTYPE_CUBE_TEXTURE
:
hr
=
cubetexture_init
(
object
,
desc
,
level_count
,
surface_flags
,
device
,
parent
,
parent_ops
);
break
;
default:
ERR
(
"Invalid resource type %s.
\n
"
,
debug_d3dresourcetype
(
desc
->
resource_type
));
hr
=
WINED3DERR_INVALIDCALL
;
break
;
}
if
(
FAILED
(
hr
=
cubetexture_init
(
object
,
desc
,
level_count
,
surface_flags
,
device
,
parent
,
parent_ops
)
))
if
(
FAILED
(
hr
))
{
WARN
(
"Failed to initialize
cubetexture, returning %#x
\n
"
,
hr
);
WARN
(
"Failed to initialize
texture, returning %#x.
\n
"
,
hr
);
HeapFree
(
GetProcessHeap
(),
0
,
object
);
*
texture
=
NULL
;
return
hr
;
}
...
...
dlls/wined3d/wined3d.spec
View file @
4b3db52b
...
...
@@ -250,9 +250,7 @@
@ cdecl wined3d_swapchain_set_window(ptr ptr)
@ cdecl wined3d_texture_add_dirty_region(ptr long ptr)
@ cdecl wined3d_texture_create_2d(ptr ptr long long ptr ptr ptr)
@ cdecl wined3d_texture_create_3d(ptr ptr long ptr ptr ptr)
@ cdecl wined3d_texture_create_cube(ptr ptr long long ptr ptr ptr)
@ cdecl wined3d_texture_create(ptr ptr long long ptr ptr ptr)
@ cdecl wined3d_texture_decref(ptr)
@ cdecl wined3d_texture_generate_mipmaps(ptr)
@ cdecl wined3d_texture_get_autogen_filter_type(ptr)
...
...
include/wine/wined3d.h
View file @
4b3db52b
...
...
@@ -2366,12 +2366,7 @@ void __cdecl wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, H
HRESULT
__cdecl
wined3d_texture_add_dirty_region
(
struct
wined3d_texture
*
texture
,
UINT
layer
,
const
struct
wined3d_box
*
dirty_region
);
HRESULT
__cdecl
wined3d_texture_create_2d
(
struct
wined3d_device
*
device
,
const
struct
wined3d_resource_desc
*
desc
,
UINT
level_count
,
DWORD
surface_flags
,
void
*
parent
,
const
struct
wined3d_parent_ops
*
parent_ops
,
struct
wined3d_texture
**
texture
);
HRESULT
__cdecl
wined3d_texture_create_3d
(
struct
wined3d_device
*
device
,
const
struct
wined3d_resource_desc
*
desc
,
UINT
level_count
,
void
*
parent
,
const
struct
wined3d_parent_ops
*
parent_ops
,
struct
wined3d_texture
**
texture
);
HRESULT
__cdecl
wined3d_texture_create_cube
(
struct
wined3d_device
*
device
,
const
struct
wined3d_resource_desc
*
desc
,
HRESULT
__cdecl
wined3d_texture_create
(
struct
wined3d_device
*
device
,
const
struct
wined3d_resource_desc
*
desc
,
UINT
level_count
,
DWORD
surface_flags
,
void
*
parent
,
const
struct
wined3d_parent_ops
*
parent_ops
,
struct
wined3d_texture
**
texture
);
ULONG
__cdecl
wined3d_texture_decref
(
struct
wined3d_texture
*
texture
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment